2017-10-19 19 views
1

は、私が手に問題を抱えているPythonのAES暗号解読で作業されていませんバイトのRFC2898由来の塩、AESで暗号化されたメッセージ、パスワード、パスワード、派生IVを使用して暗号化されました。 「これは、次のとおりです。 サンプルメッセージは、「これは私の秘密の文字列、Loremのイプサムされる」とパスワードが出力されているこのメッセージはC#のRFC2898DeriveBytesは機能していますが、PythonのPBKDF2は、鍵生成およびIVは、AES仕様は暗号文は、で構成されてい 以下の通り暗号文を暗号化復号化するために

private static readonly int SALT_SIZE = 256; 
public static void Decrytor(){ 
// Encrypted Message 
      var cipherText = "i+EKwmlAF0VYh4GwDd+bGf3+yreYsPJW2Oq/w9FXjsp7RI3VqRiqtnqiAD4n6U0JJSTe2ct4B7lgrG+dHxeGcXYEYIERXvU0xnUdH+z3mRwmgYOqCU9HRUKy/z3GKISTm8qH030KTYm3YMBjnKpU8gaRcoDPP/nCiB3o5fPdyspgJgT/qt5BuvwYq7n0qg6ez/Wi4447gq/qHwG3wuuYLSBUCfmIkgGaO1KXqv3SsR8EAhrmMBmPDJfjc3sydNqs5B8J9/JvZFEZULTb8rLQZKQvgHhH9/53Bzs3zmoq0RFbgSueUbyeWb9rLAzYieTz8Yj0srG4GtwPrTPoItc6/hvx5stZ6pX8tgyk9Y3baT0JFMtGgxve7yduy8idTCQdAwRc5NOo4+CBk7P/sIw6+Q=="; 
      var key = "password"; 
      // Extract the salt from our cipherText 
      var allTheBytes = Convert.FromBase64String(cipherText); 
      var saltBytes = allTheBytes.Take(SALT_SIZE).ToArray(); 
      var cipherTextBytes = allTheBytes.Skip(SALT_SIZE).Take(allTheBytes.Length - SALT_SIZE).ToArray(); 

      var keyDerivationFunction = new Rfc2898DeriveBytes(key, saltBytes); 
      // Derive the previous IV from the Key and Salt 
      var keyBytes = keyDerivationFunction.GetBytes(32); 
      var ivBytes = keyDerivationFunction.GetBytes(16); 

      // Create a decrytor to perform the stream transform. 
      // Create the streams used for decryption. 
      // The default Cipher Mode is CBC and the Padding is PKCS7 which are both good 
      var aesManaged = new AesManaged(); 
      var decryptor = aesManaged.CreateDecryptor(keyBytes, ivBytes); 
      var memoryStream = new MemoryStream(cipherTextBytes); 
      var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); 
      var streamReader = new StreamReader(cryptoStream); 

      // Return the decrypted bytes from the decrypting stream. 
      Console.WriteLine("\n{0}\n", streamReader.ReadToEnd()); 
     } 

次のC#コードで正常に復号化されたC#コード を使用して暗号化された「パスワード」です私の秘密の文字列、Loremのイプサム」

が、私はPython2.7同等の実装に従うことによって、メッセージを解読しようとすると、それが正しく

import base64 
from Crypto.Cipher import AES 
from Crypto.Protocol import KDF 

def p_decrypt(self, text): 
    text_dec = base64.b64decode(text) 
    salt = text_dec[:256] 
    enc_txt = text_dec[256:] 
    key_bytes = KDF.PBKDF2(self.key, salt, dkLen=32) 
    iv = KDF.PBKDF2(self.key, salt) 
    cipher = AES.new(key_bytes, AES.MODE_CBC, iv) 
    return cipher.decrypt(enc_txt) 
最初の数文字を解読されていません

出力は次のとおりです。 "增" J "T列、Loremのイプサム"

予想される出力:

I "これが私の秘密の文字列、Loremのイプサムです" C#RFC2898DeriveBytesメソッドで生成されたkeyBytesとIVを使用して、問題の原因を突き止めようとしましたが、pythonコードはPBKDF2を使用してメッセージ全体を正しく復号化しません。 keyBytesとIVを生成しました。

両方のC#RFC2898DeriveBytesとPythonのPBKDF2はHMACSHA1ハッシュアルゴを用いkeyBytesを生成しているが、PythonのPBKDF2はIVコールに対して生成keyBytesの最初の16のバイトを返しているのに対し、C#のRFC2898DeriveBytes方法が異なるkeyBytes及びIVを生成します。

これに関するいくつかの有益なガイドラインを教えてください。

おかげで、 M Umer

+0

これは**初期化ベクトルを生成する適切な方法ではありません**。 ** IVは一意でなければならず、秘密である必要はありません**あなたがするべきことは、CPRNG(IVRNGCryptoServiceProviderを参照)を使ってIVを生成し、それを暗号化されたメッセージの前に付加することです。 –

+0

(明らかに、暗号化キーが1回だけ使用されている場合**上記は重要ではありません) –

答えて

1

Rfc2898DeriveBytesがので、2つの連続したコールを連結すると共に加え両方の長さと、ワンコールを行うと同じであり、ストリーミング・レスポンス・オブジェクトです。

var pbkdf2WithTwoCalls = new Rfc2898DeriveBytes(...) 
var pbkdf2WithOneCall = new Rfc2898DeriveBytes(sameParametersAsAbove); 

byte[] twoCallA = pbkdf2WithTwoCalls.GetBytes(32); 
byte[] twoCallB = pbkdf2WithTwoCalls.GetBytes(16); 

byte[] oneCall = pbkdf2WithOneCall.GetBytes(32 + 16); 

if (!oneCall.SequenceEquals(twoCallA.Concat(twoCallB)) 
    throw new TheUniverseMakesNoSenseException(); 

だから、Pythonであなたのソリューションは、32バイトのAESキーと16バイトのIVに分割し、PBKDF2に1 48バイトの呼び出しを行うことであろう。

復号化応答は、キーが正しいことを示しますが、IVは正しくありません。

+0

上記のPythonコードは、キーの最初の16バイトをIVとして使用します。 **これが暗号化に使用された場合、これはプロセスのキーの半分をリークするでしょう!** これは、このコードの別の問題を指摘しています。IVは基本的にIVを役に立たなくします。キーのように。 ** IVはナンセンスであることを意味します**これは、それらが一度だけ使用されるべきであることを意味します。また、彼らは秘密にすることを意図していないので、通常はメッセージの一部です。 –

+0

@ErwanLegrand暗号化では、IVの最初の16バイトがIVで使用されません。「これを暗号化に使用すると、プロセスのキーの半分がリークします。 –

+0

@bartonjs、それは、あなたが本当に私の時間を保存した、ありがとう:) –

関連する問題