0

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: 暗号フィルター

4

2 に答える 2

0

私はついにすべてのドキュメントに目を通し、答えを見つけました!

モードに使用するパディング方法を指定する必要があります。NoPadding を指定した例

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

そして出来上がり!出力は pycrypto と正確に一致します。参考はこちら

于 2012-04-18T10:01:55.873 に答える
0

Base64 では末尾にパディングを含めることができます ( https://en.wikipedia.org/wiki/Base64#Decoding_Base64_with_paddingを参照) 。

どうやら Botans デコーダーはこれをサポートしていません。

おそらく binascii モジュールが役に立ちます。または、パディングを自分で追加/削除することもできます。

于 2012-04-04T09:40:19.463 に答える