如何在Python中使用RSA私钥(非常规签名)加密数据?

时间:2019-04-17 05:32:06

标签: python rsa pycrypto pycryptodome

我想使用私钥(不是正常签名)进行RSA加密,但是PyCryptodome似乎无法做到这一点。

我需要使用私钥进行操作的原因是,我需要从不是由我编写的Java程序中获得相同的结果,该Java程序错误地使用javax.crypto.Cipher和私钥对消息进行签名... < / p>

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 ......(每次更改)

1 个答案:

答案 0 :(得分:1)

您不使用私钥加密数据。

  • 私钥可以签名数据,该数据可以通过匹配的公钥进行验证
  • 公钥可以加密数据,该数据可以通过匹配的私钥进行解密

如果您真正想要的是对哈希签名,而不是使用 Container( height: 400, // width: 500, child: StreamBuilder( stream: Firestore.instance.collection('Events').where("bandId", isEqualTo:identifier ).snapshots(), builder: (BuildContext context, AsyncSnapshot snapshot) { return new Column( children: [ if (!snapshot.hasData) new Text('No Events :('), switch (snapshot.connectionState) { case ConnectionState.waiting: new Text('Loading...'); default: new Container( childe: ListView( children: snapshot.data.documents .map((DocumentSnapshot document) { return Dismissible( key: new Key(document.documentID), onDismissed: (direction){ Firestore.instance.runTransaction((transaction) async { DocumentSnapshot snapshot= await transaction.get(document.reference); await transaction.delete(snapshot.reference); }); Fluttertoast.showToast(msg: "Event Deleted"); }, child: CustomCard( event: document['event'], location: document['location'], service: document['service'], date: document['date'], ), ); }).toList(), ), ), } ]), }, ) ); 函数,则应使用encrypt函数。

所以,而不是

sign

您可能想尝试

from Crypto.Cipher import PKCS1_v1_5
PKCS1_v1_5.new(privateKey).encrypt(hash)

如果您想看一下,我写了一点blog post关于使用pycryptodome进行签名/验证。