python - 如何在 python 中使用 RSA 私钥进行加密?
问题描述
是否可以使用 pycryptodome 或任何其他库在 python 中使用私钥加密消息?我知道您不应该使用私钥加密并使用公钥解密,但我的目的是使用私钥加密,以便接收者可以确定消息是由真实作者发送的。不仅仅是安全加密,我还在寻找某种混淆。我想做一个消息是公开的应用程序,但只有你有公钥才能看到它。我试过这样做:
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
但它引发了下一个错误:TypeError: This is not a private key。
解决方案
简短的回答
- 出于安全原因,您使用的代码不允许您这样做
- 下面的替代代码
长答案
我对你的问题很好奇,然后我开始尝试编码
过了一会儿,我意识到如果你运行这个代码片段,你会发现它可以正常工作:
#!/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()
但是,如果您现在将最后两行 [即键的作用] 更改为:
encoded = encrypt_private_key(message, private)
decrypt_public_key(encoded, public)
并重新运行程序,您将获得TypeError: No private key
让我引用这个很棒的答案:
“事实证明,PyCrypto 只是试图防止您在这里误认为另一个,OpenSSL 或 Ruby OpenSSL 允许您同时执行以下操作:public_encrypt/public_decrypt 和 private_encrypt/private_decrypt
[...]
需要注意其他事项以使结果在实践中可用。这就是为什么 PyCrypto 中有一个专用的签名包的原因——这有效地完成了你所描述的事情,而且还处理了我提到的事情”
调整此链接后,我得到了以下代码,应该可以解决您的问题:
# 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()
最后注意事项:
推荐阅读
- c# - 如何将我的 Entry 值绑定到我的 ViewModel.cs?
- mobile-robot-toolkit - mrpt_ekf_slam_2d 不将地标与 [90, -90] 之外的偏航角相关联
- android - 如何等到完成一个呼叫列表来呼叫以下呼叫
- .net - 具有相同所需属性类型的 EF Core TPH 实体导致“引入 FOREIGN KEY 约束”异常
- talend - TAC(Talend 管理中心)与作业服务器的同步问题(尽管作业完成,作业在 tac 中仍显示“正在运行”)
- r - 在闪亮的条形图中更改条形的颜色
- sql-server - 更大的数据库几乎拥有所有磁盘空间,但有 54% 的可用空间。我必须缩小它吗?
- datatables - 防止 DataTables 自定义过滤器影响页面上的所有表
- php - 获取 AJAX 请求的初始帖子类型
- python - 当您不知道它是什么时,在数组中查找第一次值