2017-06-03 8 views
0

DBに書き込む前にいくつかのデータを暗号化し、DBから読み取る際に復号化する必要があります。私は解読しようとするこれまで、私はエラーを取得するときEncrypting and Decrypting data in an Universal Windows App対称暗号巡回冗長検査

私はここで、このガイドで利用可能なコードを使用しました

Data error (cyclic redundancy check). (Exception from HRESULT: 0x80070017)

キーは、私のように異なっていたので、私はそれがだと思いました暗号化のために一度SymmetricEncryptionHelperオブジェクトをインスタンス化し、次に復号化のために再びインスタンス化しました。これに対抗するために、私はシングルトンするクラスを変更し、私はまだ同じエラーを取得する:私は間違って行くよどこ

public class SymmetricEncryptionHelper 
{ 
    private readonly IBuffer randomBuffer; 
    private readonly IBuffer randomBufferCBC; 
    private readonly CryptographicKey cryptographicKey; 
    private readonly string algorithmName; 
    private readonly SymmetricKeyAlgorithmProvider cryptingProvider; 

    private static SymmetricEncryptionHelper _instance; 

    public static SymmetricEncryptionHelper Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new SymmetricEncryptionHelper(); 
      } 
      return _instance; 
     } 
    } 


    /// <summary> 
    /// Instantiate with a random generated buffer (not an option if 
    /// you want to persist the encryption to disk) 
    /// </summary> 
    private SymmetricEncryptionHelper() 
    { 
     algorithmName = SymmetricAlgorithmNames.AesEcbPkcs7; 
     cryptingProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName); 
     randomBuffer = CryptographicBuffer.GenerateRandom(cryptingProvider.BlockLength); 
     randomBufferCBC = null; 
     cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer); 
    } 

    /// <summary> 
    /// Instantiate with a custom generated buffer (good for 
    /// persisting the encryption to disk) 
    /// </summary> 
    /// <param name="randomBuffer">The custom generated buffer</param> 
    private SymmetricEncryptionHelper(IBuffer randomBuffer) 
     : this() 
    { 
     this.randomBuffer = randomBuffer; 
     cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer); 
    } 
    /// <summary> 
    /// Instantiate with a custom generated buffer (good for 
    /// persisting the encryption to disk) and with a custom 
    /// generated CBC buffer (is using CBC algorithms) 
    /// </summary> 
    /// <param name="randomBuffer">The custom generated buffer</param> 
    /// <param name="randomBufferCBC">The custom generated CBC buffer</param> 
    private SymmetricEncryptionHelper(IBuffer randomBuffer, IBuffer randomBufferCBC) 
     : this(randomBuffer) 
    { 
     this.randomBufferCBC = randomBufferCBC; 
    } 

    private bool IsMultipleOfBlockLength(IBuffer binaryData) 
    { 
     return (binaryData.Length % cryptingProvider.BlockLength) != 0; 
    } 
    /// <summary> 
    /// Encrypts a given string 
    /// </summary> 
    /// <param name="data">Data to be encrypted</param> 
    /// <returns>An encrypted string in Unicode</returns> 
    public string Encrypt(string data) 
    { 
     if (string.IsNullOrEmpty(data)) 
     { 
      return data; 
     } 

     var binaryData = Encoding.Unicode.GetBytes(data).AsBuffer(); 
     if (!algorithmName.Contains("PKCS7") && IsMultipleOfBlockLength(binaryData)) 
      throw new Exception("Message buffer length must be multiple of block length !!"); 
     var encryptedBinaryData = CryptographicEngine.Encrypt(cryptographicKey, binaryData, randomBufferCBC); 
     return Encoding.Unicode.GetString(encryptedBinaryData.ToArray()); 
    } 
    /// <summary> 
    /// Decrypts a string in Unicode 
    /// </summary> 
    /// <param name="encryptedData">An encrypted string in Unicode</param> 
    /// <returns>The decrypted string in Unicode</returns> 
    public string Decrypt(string encryptedData) 
    { 
     if (string.IsNullOrEmpty(encryptedData)) 
     { 
      return encryptedData; 
     } 

     try 
     { 
      var encryptedBinaryData = Encoding.Unicode.GetBytes(encryptedData).AsBuffer(); 
      var decryptedData = CryptographicEngine.Decrypt(cryptographicKey, encryptedBinaryData, randomBufferCBC); 
      return Encoding.Unicode.GetString(decryptedData.ToArray()); 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

} 

は誰でも見ることができます - 私は、エラーをGoogleで検索しましたが、見つけることができないよう私のために働く答え。

さらに、アプリケーションが閉じられると、キーを失うことになるので、ここでは何がベストプラクティスですか?パスワードをPasswordVaultに保存する必要がありますか?

+0

ECBモードは使用しないでください。安全ではありません。[ECBモード](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29)を参照して、ペンギンまでスクロールしてください。 – zaph

答えて

3

インターネット上でランダムなコードを信頼しないでください。あなたは何をしているのかを知る必要があります。 ECBモードの暗号化は、テキストメッセージや他のほとんどの暗号操作では安全ではありません。

問題は、暗号化方式で生成された暗号文のデコードに直接依存しています(Encoding.Unicode.GetString、悪いMicrosoftのUTF-16LE名を使用)。現在、暗号文には常にランダムなバイトが含まれています。これらのバイトのペアは、有効なUTF-16LEエンコード文字を構成するとは限りません。だから、通常それらは文字通りの暗号文から除外されるか、代用文字に置き換えられます。

代替文字が導入されている場合は、その特定の暗号文ブロックがランダムデータブロックに復号化され、CRCチェックが失敗します。


何らかの理由で暗号テキストをテキストとして表示する必要がある場合は、base64でエンコードします。

+0

文字列にはどのような暗号化がありますか? – Rick

+0

ランダムなIV(暗号文の先頭に)が付いたECBを除くすべてのもの。 GCMは暗号文も認証するため、良い選択です。 GCMのIVは12バイトである必要があり、決して繰り返されるべきではないことに注意してください。 –

関連する問題