Program python kecil ini harus mengenkripsi plain ke cipher menggunakan AES dalam mode CFB menggunakan kunci 128bit

from Crypto.Cipher import AES

#            1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
key   = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
iv    = b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
plain = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

aes = AES.new(key, AES.MODE_CFB, iv)
cipher = aes.encrypt(plain)

print(' '.join('{:2x}'.format(b) for b in cipher))

Saya mengambil kombinasi kunci, IV, dan sandi biasa ini dari salah satu Vektor uji NIST (CFB128VarTxt128.rsp). Untuk kombinasi khusus ini saya mengharapkan cipher:

3a d7 8e 72 6c 1e c0 2b 7e bf e9 2b 23 d9 ec 34

Tapi pycrypto menghitung

3a 81 e1 d4 b8 24 75 61 46 31 63 4b 5c 79 d6 bc

Byte pertama benar, sedangkan yang lain tidak cocok. Saya juga mencoba vektor uji yang berbeda, tetapi hasilnya tetap sama. Semua byte, kecuali byte pertama, tidak cocok.

Saya cukup yakin, bahwa vektor uji NIST valid karena saya menggunakannya sebelumnya saat menggunakan AES dengan Crypto++ dan saya juga cukup yakin, bahwa implementasi pycrypto sudah benar karena outputnya sesuai dengan alat online seperti halaman ini. Jelas, ini saya, yang menggunakan alat dengan cara yang salah ...

Adakah yang tahu, bagaimana cara mereproduksi vektor uji NIST dengan pycrypto?

Ini adalah contoh NIST

# CAVS 11.1
# Config info for aes_values
# AESVS VarTxt test data for CFB128
# State : Encrypt and Decrypt
# Key Length : 128
# Generated on Fri Apr 22 15:11:53 2011
...
COUNT = 0
KEY = 00000000000000000000000000000000
IV = 80000000000000000000000000000000
PLAINTEXT = 00000000000000000000000000000000
CIPHERTEXT = 3ad78e726c1ec02b7ebfe92b23d9ec34
2
avitase 18 Agustus 2017, 19:18

2 jawaban

Jawaban Terbaik

Anda kehilangan argumen kata kunci, segment_size, di Anda AES.new(...) panggilan. Ini adalah ukuran umpan balik, dan defaultnya adalah 8. Jika baris kode Anda diubah menjadi

aes = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

Anda mendapatkan hasil yang benar.

Seperti yang dinyatakan dalam dokumen:

segment_size (integer) - (Hanya MODE_CFB).Jumlah bit plaintext dan ciphertext yang tersegmentasi. Ini harus kelipatan 8. Jika 0 atau tidak ditentukan, itu akan dianggap 8.

Hasil Anda sesuai dengan apa yang kemungkinan akan diberi label "CFB8" di dokumen NIST.

3
President James K. Polk 18 Agustus 2017, 18:01

Saya juga mendapatkan hasil yang sama seperti Anda saat menggunakan AES.MODE_CFB, tetapi saya mendapatkan hasil yang Anda harapkan saat saya menggunakan AES.MODE_CBC.

from Crypto.Cipher import AES

def show(b):
    print(*['{:02x}'.format(u) for u in b])

key   = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
iv    = b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
plain = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

crypto = AES.new(key, AES.MODE_CBC, iv)
cipher = crypto.encrypt(plain)
show(cipher)

# We need a fresh AES object to decrypt
crypto = AES.new(key, AES.MODE_CBC, iv)
decoded = crypto.decrypt(cipher)
show(decoded)

keluaran

3a d7 8e 72 6c 1e c0 2b 7e bf e9 2b 23 d9 ec 34
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0
PM 2Ring 18 Agustus 2017, 17:45