[英]How can I encrypt with a RSA private key in python?
Is it possible to encrypt a message with a private key in python using pycryptodome or any other library?是否可以使用 pycryptodome 或任何其他库在 python 中使用私钥加密消息? I know that you are not supposed to encrypt with the private key and decrypt with the public key, but my purpose is to encrypt with the private one so the receiver could be sure that the message was send by the real author.我知道你不应该用私钥加密并用公钥解密,但我的目的是用私钥加密,以便接收者可以确定消息是由真正的作者发送的。 More than secure encryption I'm looking for some kind of obfuscation.不仅仅是安全加密,我正在寻找某种混淆。 I want to do an app where the message is public but it can only be seen if you have the public key.我想做一个消息是公开的应用程序,但只有在您拥有公钥时才能看到它。 I've tried to do this:我试过这样做:
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64
def generate_keys():
modulus_lenght = 256 * 4
private_key = RSA.generate(modulus_lenght, Random.new().read)
public_key = private_key.publickey()
return private_key, public_key
def encrypt_private_key(a_message, private_key):
encryptor = PKCS1_OAEP.new(private_key)
encrypted_msg = encryptor.encrypt(a_message)
encoded_encrypted_msg = base64.b64encode(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)
decoded_decrypted_msg = encryptor.decrypt(decoded_encrypted_msg)
return decoded_decrypted_msg
private_key, public_key = generate_keys()
message = "Hello world"
encoded = encrypt_private_key(message, private_key)
decoded = decrypt_public_key(encoded, public_key)
print decoded
But it raises the next error: TypeError: This is not a private key.但它引发了下一个错误:TypeError:这不是私钥。
Short answer简答
Long answer长答案
I was curious about your problem and then I started to try to code我对你的问题很好奇,然后我开始尝试编码
After a while I realized that if you run this snippet you will see that it correctly works:过了一会儿,我意识到如果你运行这个代码段,你会看到它正常工作:
#!/usr/bin/env python
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64
def generate_keys():
modulus_length = 1024
key = RSA.generate(modulus_length)
#print (key.exportKey())
pub_key = key.publickey()
#print (pub_key.exportKey())
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)
#return 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()
but if you now change two of the final lines [ie the role of the keys] into:但是,如果您现在将最后两行 [即键的作用] 更改为:
encoded = encrypt_private_key(message, private)
decrypt_public_key(encoded, public)
and rerun the program you will get the TypeError: No private key
并重新运行程序,你会得到TypeError: No private key
Let me quote from this great answer :让我引用这个伟大的答案:
"As it turns out, PyCrypto is only trying to prevent you from mistaking one for the other here, OpenSSL or Ruby OpenSSL allow you for example to do both: public_encrypt/public_decrypt and private_encrypt/private_decrypt “事实证明,PyCrypto 只是试图防止您在这里将一个误认为另一个,例如 OpenSSL 或 Ruby OpenSSL 允许您同时执行以下操作:public_encrypt/public_decrypt 和 private_encrypt/private_decrypt
[...] [...]
Additional things need to be taken care of to make the result usable in practice.需要注意其他事情才能使结果在实践中可用。 And that's why there is a dedicated signature package in PyCrypto - this effectively does what you described, but also additionally takes care of the things I mentioned"这就是为什么 PyCrypto 中有一个专用的签名包- 这有效地完成了你所描述的,而且还处理了我提到的事情”
Adapting this link I came to the following code that should solve your question:改编此链接,我来到了以下应该解决您问题的代码:
# RSA helper class for pycrypto
# Copyright (c) Dennis Lee
# Date 21 Mar 2017
# Description:
# Python helper class to perform RSA encryption, decryption,
# signing, verifying signatures & keys generation
# Dependencies Packages:
# pycrypto
# Documentation:
# https://www.dlitz.net/software/pycrypto/api/2.6/
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):
#RSA encryption protocol according to PKCS#1 OAEP
cipher = PKCS1_OAEP.new(pub_key)
return cipher.encrypt(message)
def decrypt(ciphertext, priv_key):
#RSA encryption protocol according to PKCS#1 OAEP
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)
# https://docs.python.org/3/library/base64.html
# encodes the bytes-like object s
# returns bytes
encrypted = b64encode(rsa.encrypt(msg1, private))
# decodes the Base64 encoded bytes-like object or ASCII string s
# returns the decoded bytes
decrypted = rsa.decrypt(b64decode(encrypted), private)
signature = b64encode(rsa.sign(msg1, private, "SHA-512"))
verify = rsa.verify(msg1, b64decode(signature), public)
#print(private.exportKey('PEM'))
#print(public.exportKey('PEM'))
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()
Final notes:最后说明:
print
s have ascii
because as stated here "In case of base64 however, all characters are valid ASCII characters"最后print
■找ascii
因为说这里“为Base64的情况下,但是,所有的字符都是有效的ASCII字符”Looks like pycrypto
has not been under active development since 2014 and support ended at python 3.3.看起来pycrypto
自 2014 年以来一直没有积极开发,支持在 python 3.3 结束。 cryptography
seems like the standard now. cryptography
现在似乎是标准。
Using cryptography
:使用cryptography
:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
password = b'thepassword'
key = rsa.generate_private_key(
backend=default_backend(),
public_exponent=65537,
key_size=2048
)
private_key = key.private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.BestAvailableEncryption(password)
)
public_key = key.public_key().public_bytes(
serialization.Encoding.OpenSSH,
serialization.PublicFormat.OpenSSH
)
What you are describing is called message signing and it uses private/public keys to verify that the message did come from the claimed sender and that it has not been tampered with en route.您所描述的称为消息签名,它使用私钥/公钥来验证消息确实来自声称的发件人,并且在途中没有被篡改。 You don't have to "invent" these methods ...你不必“发明”这些方法......
https://medium.com/@securegns/implementing-asymmetric-encryption-to-secure-your-project-35368049cb5f https://medium.com/@securegns/implementing-asymmetric-encryption-to-secure-your-project-35368049cb5f
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.