【发布时间】:2019-08-17 08:26:31
【问题描述】:
我正在使用带有私钥/公钥的 RSA。我正在尝试加密字符串,将其保存在数据库(sqlite)中,然后再次检索并加密。
当数据从 sqlite 出来时,我无法再次解密数据。字符串是相同的,我有点迷茫。
#!/usr/bin/env python3
from Crypto.PublicKey import RSA
from Crypto import Random
import sqlite3
import base64
# database layout
#
# CREATE TABLE secrets ( id INT, secret TEXT );
# INSERT INTO secrets (id,secret) VALUES (1,"");
# database
conn = sqlite3.connect('database.db')
c = conn.cursor()
# generate keys
private_key = RSA.generate(1024, Random.new().read)
public_key = private_key.publickey()
# save keys
f = open('public.pem', 'wb+')
f.write(public_key.exportKey('PEM'))
f.close()
f = open('private.pem', 'wb+')
f.write(private_key.exportKey('PEM'))
f.close()
# crypt
f = open('public.pem','rb')
encrypt_public_key = RSA.importKey(f.read())
secret = "123456"
enc_secret = encrypt_public_key.encrypt(secret.encode("utf-8"), 32)[0]
enc_secret_encoded = base64.b64encode(enc_secret)
print("Base64: " + str(enc_secret_encoded))
# save in db
c.execute('UPDATE secrets SET secret="%s" WHERE id=1' % (enc_secret_encoded))
conn.commit()
print("--------------- DECRYPTION ------------------------")
# decrypt
p = open('private.pem','rb')
decrypt_private_key = RSA.importKey(p.read())
c.execute('SELECT secret FROM secrets WHERE id=1')
result = c.fetchone()
encoded_secret = result[0]
print("Base64: " + encoded_secret)
decoded_secret = base64.b64decode(encoded_secret)
enc_secret = decrypt_private_key.decrypt(decoded_secret)
print("Decrypted: " + str(enc_secret))
输出:
$ ./stuck.py
Base64: b'bfAERXPFvrDRdr5Pcexu8JgHlKfDaUhkqJrSWZJbLwlKLWY8XHtIlBwrRfP7eMX9PTKo4t2CtpdXS6Fam4B+jR3/bYPxji0rHt1Aed64sLH4xAnxgh5B/qWidcYT5cPmvwMekGbCaMSgGjvNB4Js/yDRrW4+N8dqx3IoUAl8zgA='
--------------- DECRYPTION ------------------------
Base64: b'bfAERXPFvrDRdr5Pcexu8JgHlKfDaUhkqJrSWZJbLwlKLWY8XHtIlBwrRfP7eMX9PTKo4t2CtpdXS6Fam4B+jR3/bYPxji0rHt1Aed64sLH4xAnxgh5B/qWidcYT5cPmvwMekGbCaMSgGjvNB4Js/yDRrW4+N8dqx3IoUAl8zgA='
Decrypted: b'\x90\x07\xa2}\x96w\xda\xd3h\xf1\xd4\xc6z\xa5\xf3\x85\x97\xeb\xcfL\x0e\x1f;\x18\xd5\x98\xb3\xb2\xd0\x93.\xc9z\x1c\xc8\xac\xe4x\xbfT\xe4{\x1b\x19\xda\xfb/?A\xda_\xceHc\xd14X\x94\x8a\x94\xfc\x12\xc4\x86\xc9\x16\xc9b\xbf\xdaJ\xcf\xff\xe1J\x95\x03&\xda\x98\x9f\x10\xb1\tzW\xea\x9b\xd2\x13\xc1\x8d\x19\xe97\xd6\xeay\xf3\x83\xb7\xcf\xd3v\\`~\x07\xcea(\x81\xe1c\x08\x0b\x8c\xee\xc2\x87\xed\xc8\x08D\x8e\xe5\x83\xf4'
当您运行我的示例时,您会看到相同的加密字符串会再次进入 sqlite 并再次退出,但是为什么我不能再次解密并获得与 secret 相同的结果?
更新:当我删除 sqlite 数据库时,它会按预期工作。所以问题一定出在存储或检索数据的某个地方。
任何提示表示赞赏。
【问题讨论】:
-
我认为您不应该使用 RSA 密钥直接加密/解密数据。我在the documentation 中找不到
RsaKey.encode或Rsa.decode。尝试使用基于 RSA 的混合加密方案,如 here 所示。 -
对于 RSA,您需要至少 2048 位安全性。这将使您的数据非常庞大。你为什么不使用AES?此外,在您的 RSA 中,您不使用填充方案作为 PKCS#1.5,这将容易受到许多攻击。
-
@kelalaka 我同意这两个,这只是一个例子,可以减少分心来理解为什么它不起作用。
标签: python sqlite cryptography rsa pycrypto