0

我设法让 AES/Rijndael [256 位密钥/128 位块大小] 对称加密工作:用 pycrypto 加密并用 C++ 中的 Botan 解密。

但是,当我尝试在 python 中对加密结果进行 base64 编码时,生成的字符串比 Botan 使用 Base64_Encoder 生成的相同字符串短。例子:

Botan Base64:

zjjxmJf5KPs183I/EvC+JuNbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM7gLgLV+xtSKcsCeQD7Gy4w==

Py-3k Base64:

zjjxmJf5KPs183I/EvC+JuNbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM

您可以看到字符串在 64 个字符标记之前完全相同。如果我尝试在 Botan 中解密 Python base64 字符串,它会抱怨“输入不足”。

如何让 Botan 接受 Python base64 字符串?

-- 编辑 -- 在 Python 中解码 Botan base64 编码字符串时:

Botan Decoded:[b'\xce8\xf1\x98\x97\xf9(\xfb5\xf3r?\x12\xf0\xbe&\xe3[9\xd9\x9b\x9b\x86\xd6\xca\x12\xecu\x92<~\xe5T\x9c\xa4\x00y(\xf4\x8a\xf9\x8a!\x8b\xbb\x1c\x18\xcc\xee\x02\xe0-_\xb1\xb5"\x9c\xb0\'\x90\x0f\xb1\xb2\xe3']
Botan Encoded:[b'zjjxmJf5KPs183I/EvC+JuNbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM7gLgLV+xtSKcsCeQD7Gy4w==']

因此,Python pycrypto 结果:

Encryption result: b'\xce8\xf1\x98\x97\xf9(\xfb5\xf3r?\x12\xf0\xbe&\xe3[9\xd9\x9b\x9b\x86\xd6\xca\x12\xecu\x92<~\xe5T\x9c\xa4\x00y(\xf4\x8a\xf9\x8a!\x8b\xbb\x1c\x18\xcc'

Base64 encoded: b'zjjxmJf5KPs183I/EvC+JuNbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM

Python似乎“省略”了一些东西。但是什么?

-- 编辑 2 --

当我尝试对 pycrypto 结果进行 base64decode 和解密时,Botan 抛出这个:

Botan exception caught: Buffered_Operation::final - not enough input

所以 pycrypto 没有产生“足够”的输出,以至于它可以被 Botan 解密。

-- 编辑 3 --- 代码示例:

Python:更改了敏感信息。

import sys
import base64
import binascii
from Crypto.Cipher import AES

plaintext = "097807897-340284-083-08-8034-0843324890098324948"

hex_key = b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
key = binascii.unhexlify( hex_key )
hex_iv = b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
iv = binascii.unhexlify( hex_iv )

aes_enc_bytes = AES.new(key, AES.MODE_CBC, iv).encrypt( plaintext )
aes_enc = base64.encodebytes(aes_enc_bytes )

print( "Encrypted:[{}]".format( aes_enc ) )

aes_dec = AES.new(key, AES.MODE_CBC, iv).decrypt( binascii.a2b_base64( aes_enc ) )
print( "Decrypted:[{}]".format( aes_dec ) )

C++ (Qt + Botan)

void botanDecryptor::decrypt()
{
    Botan::SymmetricKey key( private_key );
    Botan::InitializationVector iv( iv_value );
    try
    {
        // Now decrypt...
        Botan::Pipe dec_pipe(new Base64_Decoder, get_cipher("AES-256/CBC", key, iv, Botan::DECRYPTION));

        dec_pipe.process_msg( ciphertext );

        string decrypted = dec_pipe.read_all_as_string();

        cout << "Decrypted:[" << decrypted << "]" << endl;
    }
    catch(Botan::Exception& e)
    {
        cout << "Botan exception caught: " << e.what() << endl;
        return;
    }

-- 编辑 4 --

我决定尝试在 python 中解密 Botan 加密的、base64 编码的字符串,它可以工作,但它添加了一堆看起来像填充的东西:

Decrypted:[b'097807897-340284-083-08-8034-0843324890098324948\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10']

然后我继续在base64编码之前将该填充添加到我的pycrypto结果中以生成以下内容,Botan拒绝解密;(

zjjxmJf5KPs183I/EvC+JuNbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjMEBAQEBAQEBAQ\nEBAQEBAQEA==

-- ANSWER -- (系统不允许我再过 5 个小时自行回答!)

我终于浏览了所有文档并找到了答案!需要指定要用于该模式的填充方法。我指定了 NoPadding 例如

Pipe dec_pipe(new Base64_Decoder, get_cipher("AES-256/CBC/NoPadding", key, iv, Botan::DECRYPTION));

和中提琴!输出与 pycrypto 完全匹配。供参考:[http://botan.randombit.net/filters.html][1]

[1]:Botan Docs:密码过滤器

4

2 回答 2

0

Base64 可以在末尾有一个填充(参见https://en.wikipedia.org/wiki/Base64#Decoding_Base64_with_padding

显然,Botans 解码器不支持这一点。

也许 binascii 模块可以帮助你;或者,您可以自己添加/删除填充。

于 2012-04-04T09:40:19.463 回答
0

我终于浏览了所有文档并找到了答案!

需要指定要用于该模式的填充方法。我指定了 NoPadding 例如

Pipe dec_pipe(new Base64_Decoder, get_cipher("AES-256/CBC/NoPadding", key, iv, Botan::DECRYPTION));

and voila! The output matches the pycrypto exactly. Here's the reference.

于 2012-04-18T10:01:55.873 回答