如何使用PyCrypto添加/更改RSA私钥密码

6 投票
2 回答
6395 浏览
提问于 2025-04-16 22:39

也许有人能帮我一下。我正在使用PyCrypto来生成一对RSA密钥,包括公钥和私钥。我想给私钥添加或更改一个密码,但我不知道该怎么做。

这是我代码的一部分。

#encoding:utf-8
from Crypto.PublicKey import RSA

pass_alice='ala'
private_alice_key = RSA.generate(1024)
public_alice_key  = private_alice_key.publickey()

str_priv = private_alice_key.exportKey()
str_pub  = public_alice_key.exportKey()

print str_priv
print str_pub

# HOW ADD OR CHANGE PASSWORD FOR private_alice_key

在M2Crypt中,生成RSA密钥对的函数generate pair key RSA.gen_key可以接受一个回调函数参数,这样我就可以返回我自己的密码。

#example in M2Crypt:
from M2Crypto import RSA
key = RSA.gen_key(1024, 6528, lambda pass:'my_password')

那么在PyCrypto中该怎么做呢?谢谢大家的回复。

2 个回答

1

关于如何加载带短语的密钥,可以查看RSA模块的说明

importKey的说明

importKey(externKey, passphrase=None)

这个功能用于导入一个RSA密钥(可以是公钥或私钥),它的格式是标准的。

具体可以参考RSAImplementation.importKey。

参数:

  • externKey(字符串)- 要导入的RSA密钥,以字符串形式编码。

    RSA公钥可以有以下几种格式:

    • X.509 subjectPublicKeyInfo DER SEQUENCE(可以是二进制或PEM编码)
    • PKCS#1 RSAPublicKey DER SEQUENCE(可以是二进制或PEM编码)
    • OpenSSH(仅限文本公钥)

    RSA私钥可以有以下几种格式:

    • PKCS#1 RSAPrivateKey DER SEQUENCE(可以是二进制或PEM编码)
    • PKCS#8 PrivateKeyInfo DER SEQUENCE(可以是二进制或PEM编码)
    • OpenSSH(仅限文本公钥)

    关于PEM编码的详细信息,可以参考RFC1421/RFC1423。

    如果是PEM编码,私钥可以根据某个短语用DES或3TDES加密。只有与OpenSSL兼容的短语才被支持。

  • passphrase(字符串)- 如果是加密的PEM密钥,这就是用来生成加密密钥的短语。

返回值:

返回一个RSA密钥对象(_RSAobj)。

可能出现的错误:

  • ValueError/IndexError/TypeError - 当给定的密钥无法解析时(可能是因为短语错误)。

示例:

from Crypto import RSA

key = RSA.generate(1024)
exportedKey = key.exportKey('PEM', 'my secret', pkcs=1)

关于如何保存带短语的密钥,可以查看_RSAobj对象的说明

exportKey的说明

exportKey(self, format='PEM', passphrase=None, pkcs=1)

这个功能用于导出RSA密钥。

参数:

  • format(字符串)- 用于包装密钥的格式。
    • 'DER'。二进制编码,始终不加密。
    • 'PEM'。文本编码,按照RFC1421/RFC1423进行。可以选择不加密(默认)或加密。
    • 'OpenSSH'。文本编码,按照OpenSSH规范进行。仅适用于公钥(不适用于私钥)。
  • passphrase(字符串)- 如果是PEM格式,这是用来生成加密密钥的短语。
  • pkcs(整数)- 用于组装密钥的PKCS标准。你有两个选择:

    • 选择1时,公钥嵌入到X.509 SubjectPublicKeyInfo DER SEQUENCE中。私钥嵌入到PKCS#1 RSAPrivateKey DER SEQUENCE中。这是默认模式。
    • 选择8时,私钥嵌入到PKCS#8 PrivateKeyInfo DER SEQUENCE中。这个模式不适用于公钥。 PKCS标准与OpenSSH格式无关。

返回值:

返回一个字节字符串,包含编码后的公钥或私钥。

可能出现的错误:

  • ValueError - 当格式未知时。

示例:

from Crypto.PublicKey import RSA

with open("key.pem", "r") as privatekey:
    encryptor = RSA.importKey(privatekey, passphrase="my secret")
2

PyCrypto没有可以管理RSA密码短语的功能。

不过,你可以使用ezPyCrypto主页)这个模块,它是建立在PyCrypto模块之上的。这个模块的界面更简单,可以让你:

  • 生成、导出和导入公钥和私钥
  • 轻松加密和解密字符串
  • 可选地将加密数据创建为适合邮件发送的文本
  • 对字符串(包括文档)进行签名和验证
  • 用密码短语保护你的私钥
  • 创建“流”,用于通过安全的套接字发送数据
  • 选择你喜欢的任何公钥大小(推荐2048位)
  • 在公钥中选择RSA或ElGamal,在会话密钥中选择IDEA、DES3、Blowfish、ARC4、IDEA
  • 安心使用256位会话密钥,并防御常见的RSA和ElGamal攻击,让那些想侵犯你隐私的人感到无比沮丧。

使用方法:

"""
example7.py
Demonstrate the use of passphrases with private keys
"""
import ezPyCrypto

mysecret = "Don't look at this!!!"
raw = "Here is a string to encrypt"

# Create a key object
k = ezPyCrypto.key(passphrase=mysecret)

# Export public/private key
publicAndPrivateKey = k.exportKeyPrivate()

# Encrypt against this keypair
enc = k.encString(raw)

# Create a new key object, and import keys (with passphrase)
k1 = ezPyCrypto.key(publicAndPrivateKey, passphrase=mysecret)

# Decrypt text
dec = k.decString(enc)

# test
if dec == raw:
    print "Successful decryption using correct passphrase"
else:
    print "Failed somewhere"

print "Trying now with a bad passphrase"
try:
    k2 = ezPyCrypto.key(publicAndPrivateKey, passphrase="cracking attempt")
except ezPyCrypto.CryptoKeyError:
    print "Oops - our feeble cracking attempt failed (which is a good thing)."
else:
    print "Cracking attempt succeeded - we're not safe"
    # We're in - let's plunder
    dec2 = k2.decString(enc)

构建它

如果你查看ezCryptoPy的源代码,你会发现密钥实际上是通过使用BlueFish算法进行加密/解密的:

   # decrypt against passphrase
        blksiz = 8 # lazy of me

        # create temporary symmetric cipher object for passphrase - 
        #hardwire to Blowfish
        ppCipher = Blowfish.new(passphrase,
                                Blowfish.MODE_CFB,
                                self._passIV[0:blksiz])
        enclen = len(keyobj)
        decpriv = ''
        i = 0
        while i < enclen:
            decbit = ppCipher.decrypt(keyobj[i:i+blksiz])
            decpriv += decbit
            i += blksiz
        keyobj = decpriv[0:size]

这意味着,你可以使用之前的代码示例编写自己的密码短语处理程序,而不需要安装ezPyCrypto。在这里你可以找到很多代码示例,教你如何自己动手: Nullege代码搜索

我的第一个和替代方案:

你可以使用Python的exec()函数和命令行工具“ssh-keygen”(文档):

ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]

撰写回答