Python到C#AES CBC PKCS7

Eon*_*dan 8 c# python encryption cryptography aes

我正在尝试将此C#代码转换为Python(2.5,GAE).问题是每次加密(在同一个字符串上)时,python脚本中的加密字符串都不同.

string Encrypt(string textToEncrypt, string passphrase)
 {
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    rijndaelCipher.Mode = CipherMode.CBC;
    rijndaelCipher.Padding = PaddingMode.PKCS7;

    rijndaelCipher.KeySize = 128;
    rijndaelCipher.BlockSize = 128;
    byte[] pwdBytes = Encoding.UTF8.GetBytes(passphrase);
    byte[] keyBytes = new byte[16];
    int len = pwdBytes.Length;
    if (len > keyBytes.Length)
    {
        len = keyBytes.Length;
    }
    Array.Copy(pwdBytes, keyBytes, len);
    rijndaelCipher.Key = keyBytes;
    rijndaelCipher.IV = new byte[16];
    ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
    byte[] plainText = Encoding.UTF8.GetBytes(textToEncrypt);
    return Convert.ToBase64String(transform.TransformFinalBlock(plainText, 0, plainText.Length));
}
Run Code Online (Sandbox Code Playgroud)

Python代码:(PKCS7Encoder:http://japrogbits.blogspot.com/2011/02/using-encrypted-data-between-python-and.html )

from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder
#declared outside of all functions
key = '####'
mode = AES.MODE_CBC
iv = '\x00' * 16
encryptor = AES.new(key, mode, iv)
encoder = PKCS7Encoder()

def function(self):
 text = self.request.get('passwordTextBox')
 pad_text = encoder.encode(text)
 cipher = encryptor.encrypt(pad_text)
 enc_cipher = base64.b64encode(cipher)
Run Code Online (Sandbox Code Playgroud)

C#代码是继承的.Python代码必须以相同的方式加密和解密,以便C#代码可以正确解码值.

注意:我是python的菜鸟:)

编辑:抱歉.应该区分出有一个函数被调用.

谢谢!

Tai*_*ils 3

您的 C# 代码无效。

Encrypt函数接受密码短语 asstring passphrase但然后尝试在这一行中引用它byte[] pwdBytes = Encoding.UTF8.GetBytes(key);

改成。keypassphrase

现在,这两个函数对我产生相同的结果:

Python

secret_text = 'The rooster crows at midnight!'
key = 'A16ByteKey......'
mode = AES.MODE_CBC
iv = '\x00' * 16

encoder = PKCS7Encoder()
padded_text = encoder.encode(secret_text)

e = AES.new(key, mode, iv)
cipher_text = e.encrypt(padded_text)

print(base64.b64encode(cipher_text))

# e = AES.new(key, mode, iv)
# cipher_text = e.encrypt(padded_text)
# print(base64.b64encode(cipher_text))
Run Code Online (Sandbox Code Playgroud)

C#(修复了上面提到的拼写错误)

Console.WriteLine(Encrypt("The rooster crows at midnight!", "A16ByteKey......"));
Run Code Online (Sandbox Code Playgroud)

Python 结果

XAW5KXVbItrc3WF0xW175UJoiAfonuf+s54w2iEs+7A=

C# 结果

XAW5KXVbItrc3WF0xW175UJoiAfonuf+s54w2iEs+7A=

我怀疑你在 python 代码中多次重复使用“e”。如果取消注释 python 脚本的最后两行,您将看到输出现在有所不同。但如果取消最后三行的注释,您将看到输出是相同的。正如 Foon 所说,这是由于CBC 的运作方式所致。

CBC(密码块链接)在加密块中的字节序列时起作用。第一个块通过将 IV 与明文的第一个字节(“公鸡...”)合并来加密。第二个块使用第一个操作的结果而不是 IV。

当您e.encrypt()第二次调用时(例如,取消注释 python 脚本的最后两行),您将从上次中断的地方继续。加密第一个块时,它将使用最后一个加密块的输出,而不是使用 IV。这就是结果看起来不同的原因。通过取消注释 python 脚本的最后三行,您可以初始化一个新的加密器,该加密器将使用 IV 作为其第一个块,从而获得相同的结果。