在python中使用密码创建RSA密钥

Cha*_*ker 7 python encryption rsa sign

我希望能够在python中单独从密码(和盐)生成和重新生成相同的RSA密钥.

目前我使用pycrypto进行此操作,但是,它似乎没有单独从密码生成相同的确切密钥.原因似乎是当pycrypto生成RSA密钥时,它在内部使用某种随机数.

目前我的代码如下:

import DarkCloudCryptoLib as dcCryptoLib #some costume library for crypto
from Crypto.PublicKey import RSA

password = "password"


new_key1 = RSA.generate(1024) #rsaObj
exportedKey1 = new_key1.exportKey('DER', password, pkcs=1)
key1 = RSA.importKey(exportedKey1)

new_key2 = RSA.generate(1024) #rsaObj
exportedKey2 = new_key2.exportKey('DER', password, pkcs=1)
key2 = RSA.importKey(exportedKey2)
print dcCryptoLib.equalRSAKeys(key1, key2) #wish to return True but it doesn't
Run Code Online (Sandbox Code Playgroud)

我真的不在乎我是否必须不使用pycrypto,只要我可以单独从密码和盐生成这些RSA密钥.

我在这里先向您的帮助表示感谢.

仅供参考,这是dcCryptoLib.equalRSAKeys(key1,key2)函数的样子:

def equalRSAKeys(rsaKey1, rsaKey2):
    public_key = rsaKey1.publickey().exportKey("DER") 
    private_key = rsaKey1.exportKey("DER") 
    pub_new_key = rsaKey2.publickey().exportKey("DER")
    pri_new_key = rsaKey2.exportKey("DER")
    boolprivate = (private_key == pri_new_key)
    boolpublic = (public_key == pub_new_key)
    return (boolprivate and boolpublic)
Run Code Online (Sandbox Code Playgroud)

注意:另外,我只使用RSA进行身份验证.因此,任何提供生成安全非对称签名/验证密码生成方法的解决方案都是我的应用程序可接受的解决方案.虽然,从我感觉到的密码生成RSA密钥,这个问题也应该得到回答,因为如果正确使用它似乎很有用.

Ilm*_*nen 5

如果您尝试使用共享密码实施经过身份验证的加密方案,则实际上并不需要RSA密钥:您只需要一个用于加密的AES密钥和一个用于身份验证的HMAC密钥.

如果您确实需要生成不知道密码而不能验证的非对称签名,那么您将不得不以某种方式基于密码以确定的方式生成RSA(或DSA等)密钥.根据文档,这应该可以通过定义自定义来实现randfunc,如下所示:

from Crypto.Protocol.KDF import PBKDF2
from Crypto.PublicKey import RSA

password = "swordfish"   # for testing
salt = "yourAppName"     # replace with random salt if you can store one

master_key = PBKDF2(password, salt, count=10000)  # bigger count = better

def my_rand(n):
    # kluge: use PBKDF2 with count=1 and incrementing salt as deterministic PRNG
    my_rand.counter += 1
    return PBKDF2(master_key, "my_rand:%d" % my_rand.counter, dkLen=n, count=1)

my_rand.counter = 0
RSA_key = RSA.generate(2048, randfunc=my_rand)
Run Code Online (Sandbox Code Playgroud)

我已经测试了这个,它确实生成了确定性的RSA密钥(至少你记得要重置计数器).但请注意,这不是100%面向未来的:如果pycrypto RSA密钥生成算法以某种方式更改,生成的密钥可能会更改.

在任何一种情况下,您几乎肯定都希望使用慢速键拉伸 KDF(如PBKDF2)预处理密码,迭代次数可以合理容忍.这使得通过暴力密码猜测破坏您的系统相当简单.(当然,你仍然需要使用强密码;如果你的密码是密码,那么任何密钥拉伸都不会有帮助abc123.)