简短回答
- 由于安全原因,您正在使用的代码不允许您这样做
- 以下是备选代码
详细回答
我对您的问题感到好奇,然后开始尝试编码
过了一会儿,我意识到如果您运行此片段,您将看到它能够正确工作:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64
def generate_keys():
modulus_length = 1024
key = RSA.generate(modulus_length)
pub_key = key.publickey()
return key, pub_key
def encrypt_private_key(a_message, private_key):
encryptor = PKCS1_OAEP.new(private_key)
encrypted_msg = encryptor.encrypt(a_message)
print(encrypted_msg)
encoded_encrypted_msg = base64.b64encode(encrypted_msg)
print(encoded_encrypted_msg)
return encoded_encrypted_msg
def decrypt_public_key(encoded_encrypted_msg, public_key):
encryptor = PKCS1_OAEP.new(public_key)
decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg)
print(decoded_encrypted_msg)
decoded_decrypted_msg = encryptor.decrypt(decoded_encrypted_msg)
print(decoded_decrypted_msg)
def main():
private, public = generate_keys()
print (private)
message = b'Hello world'
encoded = encrypt_private_key(message, public)
decrypt_public_key(encoded, private)
if __name__== "__main__":
main()
但如果您现在将最后两行代码(即密钥的作用)更改为:
encoded = encrypt_private_key(message, private)
decrypt_public_key(encoded, public)
如果您重新运行程序,您将收到TypeError: No private key
错误。引用自这个问题的答案:
"正如事实证明的那样,PyCrypto只是试图防止您在此处将一个错误地误解为另一个,OpenSSL或Ruby OpenSSL例如允许您执行公共加密/公共解密和私有加密/私有解密。
[...]
为使结果在实践中可用,需要额外注意一些事项。这就是为什么在PyCrypto中有一个专门的签名包 - 这实际上做了您所描述的事情,但还另外处理了我提到的事情"
根据这个链接进行调整,我得出了以下代码,应该可以解决您的问题:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
import rsa
hash = "SHA-256"
def newkeys(keysize):
random_generator = Random.new().read
key = RSA.generate(keysize, random_generator)
private, public = key, key.publickey()
return public, private
def importKey(externKey):
return RSA.importKey(externKey)
def getpublickey(priv_key):
return priv_key.publickey()
def encrypt(message, pub_key):
cipher = PKCS1_OAEP.new(pub_key)
return cipher.encrypt(message)
def decrypt(ciphertext, priv_key):
cipher = PKCS1_OAEP.new(priv_key)
return cipher.decrypt(ciphertext)
def sign(message, priv_key, hashAlg="SHA-256"):
global hash
hash = hashAlg
signer = PKCS1_v1_5.new(priv_key)
if (hash == "SHA-512"):
digest = SHA512.new()
elif (hash == "SHA-384"):
digest = SHA384.new()
elif (hash == "SHA-256"):
digest = SHA256.new()
elif (hash == "SHA-1"):
digest = SHA.new()
else:
digest = MD5.new()
digest.update(message)
return signer.sign(digest)
def verify(message, signature, pub_key):
signer = PKCS1_v1_5.new(pub_key)
if (hash == "SHA-512"):
digest = SHA512.new()
elif (hash == "SHA-384"):
digest = SHA384.new()
elif (hash == "SHA-256"):
digest = SHA256.new()
elif (hash == "SHA-1"):
digest = SHA.new()
else:
digest = MD5.new()
digest.update(message)
return signer.verify(digest, signature)
def main():
msg1 = b"Hello Tony, I am Jarvis!"
msg2 = b"Hello Toni, I am Jarvis!"
keysize = 2048
(public, private) = rsa.newkeys(keysize)
encrypted = b64encode(rsa.encrypt(msg1, private))
decrypted = rsa.decrypt(b64decode(encrypted), private)
signature = b64encode(rsa.sign(msg1, private, "SHA-512"))
verify = rsa.verify(msg1, b64decode(signature), public)
print("Encrypted: " + encrypted.decode('ascii'))
print("Decrypted: '%s'" % (decrypted))
print("Signature: " + signature.decode('ascii'))
print("Verify: %s" % verify)
rsa.verify(msg2, b64decode(signature), public)
if __name__== "__main__":
main()
最终备注:
- 最后两个
print
的结果是ascii
,因为如此处所述,“在base64的情况下,所有字符都是有效的ASCII字符”。
- 在这种情况下,我们使用相同的密钥 - 私钥 - 既用于加密又用于解密,所以是对称的,但是......
- 但是 - 如此处所述 - “公钥是公开的 - 它是你愿意共享的东西,因此很容易被传播。在这种情况下,与使用对称密码和共享密钥相比,没有增加价值”,再加上“从概念上讲,使用私钥进行“加密”更有用于签署消息,而使用公钥进行“解密”用于验证消息”。
- 此答案中表达了完全相同的原则 - “通常[...]我们说用私钥签名,用公钥验证”