我正在试图弄清楚如何将现有C函数的加密/解密镜像到python。但是,在我使用C加密和使用python解密的测试中,我无法弄清楚密钥周围的一些元素。
这些都是在线的代码示例,所以我在Python中评论了类似base64调用的内容,此时我不确定:
1)如果我正确确定KEYBIT到KEY_SIZE / BLOCK_SIZE设置。
2)如何在python中从密码到密钥以匹配C代码。
3)我错过了任何核心转换步骤吗?
rijndael.h in C:
#define KEYLENGTH(keybits) ((keybits)/8)
#define RKLENGTH(keybits) ((keybits)/8+28)
#define NROUNDS(keybits) ((keybits)/32+6)
加密C
#define KEYBITS 256
unsigned long rk[RKLENGTH(KEYBITS)];
unsigned char key[KEYLENGTH(KEYBITS)];
char *password = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
for (i = 0; i < sizeof(key); i++)
key[i] = *password != 0 ? *password++ : 0;
nrounds = rijndaelSetupEncrypt(rk, key, 256);
count = 0;
while (count < strlen(input)) {
unsigned char ciphertext[16];
unsigned char plaintext[16];
for (i = 0; i < sizeof(plaintext); i++) {
if (count < strlen(input))
plaintext[i] = input[count++];
else
plaintext[i] = 0;
}
rijndaelEncrypt(rk, nrounds, plaintext, ciphertext);
if (fwrite(ciphertext, sizeof(ciphertext), 1, output) != 1)
fclose(file);
fputs("File write error", stderr);
return 0;
}
}
用Python解密
KEY_SIZE = 32
BLOCK_SIZE = 16
def decrypt(password, filename):
#
# I KNOW THIS IS WRONG, BUT HOW DO I CONVERT THE PASSWD TO KEY?
#
key = password
padded_key = key.ljust(KEY_SIZE, '\0')
#ciphertext = base64.b64decode(encoded)
ciphertext = file_get_contents(filename);
r = rijndael(padded_key, BLOCK_SIZE)
padded_text = ''
for start in range(0, len(ciphertext), BLOCK_SIZE):
padded_text += r.decrypt(ciphertext[start:start+BLOCK_SIZE])
plaintext = padded_text.split('\x00', 1)[0]
return plaintext
谢谢!
答案 0 :(得分:0)
示例C代码只是将password
字符串中的32个字节复制到密钥中。如果密钥小于32个字节,则在右侧用零填充。
转换为python,这将是:
key = password[:32]+b'\x00'*(32-len(password))
实际上产生与
相同的结果password.ljust(32, '\0')
但是请注意,这种生成密钥的方法是extremely unsafe。如果攻击者怀疑该密钥由填充0字节的ASCII字符组成,则密钥空间(可能的密钥数量)会大大减少。如果密钥是由随机字节组成的,则有256 ^ 32 = 1.15e77个密钥。如果密钥,例如以8个ASCII字符开头,后跟零,只有(127-32)^ 8 = 6.63e15个可能的键。而且由于dictionaries有经常使用的密码,攻击者可能不必耗尽这个减少的密钥空间;他会先尝试相对较小的词典。
考虑使用cryptographic hash function或其他适当的key derivation function将密码短语转换为密钥。
尝试使用pycrypto工具包。它实现了Rijndael/AES and other ciphers。