使用Bouncy Castle在C#中进行加密,在Python中使用AES(EAX模式)解密的问题

3
我正在尝试使用C#加密文本,并在Python中使用AES的EAX模式进行解密。我在C#中使用Bouncy Castle来实现EAX,而在Python中使用AES。
我已经成功地在C#和Python中进行了加密和解密,但是我注意到当C#加密文本时,输出的长度比Python加密的要长得多。
我不确定它是否相关,但我通过服务器从C#发送它到Python,并确认一切都按照应该的方式发送。客户端运行Android模拟器,而服务器运行Windows 10。
我用来测试C#代码的方法:
const int MAC_LEN = 16
//The Key and Nonce are randomly generated
AeadParameters parameters = new AeadParameters(key, MAC_LEN * 8, nonce);

string EaxTest(string text, byte[] key, AeadParameters parameters)
{
    KeyParameter sessKey = new KeyParameter(key);
    EaxBlockCipher encCipher = new EAXBlockCipher(new AesEngine());
    EaxBlockCipher decCipher = new EAXBlockCipher(new AesEngine());

    encCipher.Init(true, parameters);
    byte[] input = Encoding.Default.GetBytes(text);
    byte[] encData = new byte[encCipher.GetOutputSize(input.Length)];
    int outOff = encCipher.ProcessBytes(input, 0, input.Length, encData, 0);
    outOff += encCipher.DoFinal(encData, outOff);

    decCipher.Init(false, parameters);
    byte[] decData = new byte[decCipher.GetOutputSize(outOff)];
    int resultLen = decCipher.ProcessBytes(encData, 0, outOff, decData, 0);
    resultLen += decCipher.DoFinal(decData, resultLen);
    return Encoding.Default.GetString(decData);
}

我正在使用的测试 Python 代码的方法:

def encrypt_text(data, key):
    cipher = AES.new(key, AES.MODE_EAX)
    nonce = cipher.nonce
    cipher_text, mac_tag = cipher.encrypt_and_digest(data)
    return [cipher_text, mac_tag, nonce]


def decrypt_text(data, key, mac_tag, nonce):
    decrypt = AES.new(key, AES.MODE_EAX, nonce=nonce, mac_len=16)
    plaintext = decrypt.decrypt_and_verify(data, mac_tag)
    return plaintext

当我使用C#对字符串"a"进行加密时,我得到了一个始终为17字节的加密文本,而在Python中,我得到了一个始终为1字节的加密文本。当我尝试在Python中解密时,出现了错误[ValueError: MAC check failed]。MAC和nonce始终都是16个字节。

C#示例输出:34 2D 0A E9 8A 37 AC 67 0E 95 DB 91 D7 8C E5 4E 9F

Python示例输出:DD

1个回答

2
C#中的默认编码是UTF-16LE,这应该给你两个明文字节和因此两个密文字节。然而,在C# / Bouncy Castle代码中,返回的密文包含16个字节的认证标签在结尾处。显然,你缺少一个字节,17个字节短了一个字节。所以密文的传输在某个地方失败了。当然,在这种情况下,认证标签的验证也将失败。
在Python中,密文是一个字节,认证标签是16个字节。这对于单个字节的输入是正确的。你的编码不在给出的代码片段中,但我假设它是UTF-8中的一个字节。
确保你在C#代码中也使用UTF-8,并确保密文被正确传输。确保在需要通过文本接口传输时使用base 64,并且不要跳过零值字节。最后,如果你使用随机nonce,请确保将其与密文一起传输(通常是前缀)。在完成所有这些之后,你应该没问题了。

谢谢!我遇到的问题与Bouncy Castle添加的密钥有关。非常感谢您的帮助! - jjwebb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接