python - 如何在 Python 中使用 RSA 私钥(非正常签名)加密数据?
问题描述
我想用私钥(不是普通签名)进行 RSA 加密,但 PyCryptodome 似乎无法做到。
我需要使用私钥执行此操作的原因是,我需要获得与不是我编写的 Java 程序相同的结果,该程序错误地使用 javax.crypto.Cipher 和私钥来签署消息......
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
...
String deviceKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASC...";
PKCS8EncodedKeySpec localPKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(deviceKey).getBytes("UTF-8"));
PrivateKey localPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(localPKCS8EncodedKeySpec);
byte[] hash = MessageDigest.getInstance("SHA-256").digest("test".getBytes());
Cipher localCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
localCipher.init(Cipher.ENCRYPT_MODE, localPrivateKey);
String sign = new String(Base64.encode(localCipher.doFinal(hash)));
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Hash import SHA256
...
deviceKey = 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASC...'
privateKey = RSA.importKey(deviceKey)
hash = SHA256.new('test'.encode()).digest()
signer = PKCS1_v1_5.new(privateKey)
sign = b64encode(signer.encrypt(hash))
Java程序的结果:
哈希:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
符号:k8y6zMfl0KVuQWWOmRxieXF1aH0dpVUX......(总是一样)
我的 Python 脚本的结果:
哈希:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
符号:GfLVqZDnu5aLHHbi0tM5OtCBEVKKRcjW......(每次都改变)
解决方案
您不使用私钥来加密数据。
- 私钥可以对数据进行签名,可以通过匹配的公钥进行验证。
- 公钥可以加密数据,可以通过匹配的私钥解密。
如果你真正想要的是签署你的哈希,而不是使用encrypt
函数,你应该使用sign
函数。
所以,而不是
from Crypto.Cipher import PKCS1_v1_5
PKCS1_v1_5.new(privateKey).encrypt(hash)
你可能想试试
from Crypto.Signature import pkcs1_15
pkcs1_15.new(privateKey).sign(hash)
我写了一篇关于使用 pycryptodome 进行签名/验证的小博文,如果你想看看的话。
推荐阅读
- azure - Azure 人脸 API 对同一个人的图像的信心减弱
- c++ - 如何修改链表中的用户输入?
- orientdb - 在 OrientDB 中使用 SQL 查找两个顶点之间排除的替代路径
- node.js - 在快速路由响应中发送 PDF 并强制浏览器下载
- tensorflow - 如何检查 tf.data 数据集对象?
- mysql - MySql-Maven-Plugin:java.sql.SQLException:用户'root'@'localhost'的访问被拒绝(使用密码:是)
- javascript - 如何为多个输入框使用虚拟键盘?
- xslt - 避免某些模式的 XSLT 模板
- php - 如何在shopify admin api中获取具有特定标签的客户数量
- android - 带有一个 RecyclerView 的网格和垂直列表