AES/Rijndael [256 ビット キー / 128 ビット ブロック サイズ] 対称暗号化を機能させることができました。pycrypto で暗号化し、C++ の Botan で復号化します。
ただし、Python で暗号化結果を base64 エンコードしようとすると、結果の文字列は、Base64_Encoder を使用して Botan によって生成された同じ文字列よりも短くなります。例:
ボタン Base64:
zjjxmJf5KPs183I/Evc+JunbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM7gLgLV+xtSKcsCeQD7Gy4w==
Py-3k Base64:
zjjxmJf5KPs183I/Evc+JunbOdmbm4bWyhLsdZI8fuVUnKQAeSj0ivmKIYu7HBjM
文字列は 64 文字のマークまではまったく同じであることがわかります。Botan で Python base64 文字列を復号化しようとすると、「十分な入力がありません」というエラーが表示されます。
Python base64 文字列を Botan で受け入れられるようにするにはどうすればよいですか?
-- 編集 -- 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 で復号化できるほど「十分な」出力を生成していません。
-- EDIT 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 + ボタン)
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 --
Botan で暗号化され、base64 でエンコードされた文字列を Python で解読してみることにしましたが、うまくいきましたが、パディングのように見えるものがたくさん追加されました。
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: 暗号フィルター