[英]RSA sign a string with private key in python
I am communicating with our clients server.我正在与我们的客户服务器通信。 For an api I need to sign a string with my private key.对于 api,我需要用我的私钥签署一个字符串。 They have the following condition to follow他们有以下条件可以遵循
and I am doing following我正在做以下
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
import base64
pkey = RSA.importKey(keystring)
message = "Hello world"
h = SHA256.new(message.encode())
signature = PKCS1_v1_5.new(pkey).sign(h)
result = base64.b64encode(signature).decode()
Here I am getting a string as result.结果我得到了一个字符串。 But on the server side my signature is not matching.但是在服务器端我的签名不匹配。
Is there anything I am going wrong with??我有什么问题吗? Can anyone help me on this?谁可以帮我这个事?
I came back to this question recently and noticed it was never resolved.我最近回到这个问题并注意到它从未得到解决。 I don't know what was going wrong with the OPs setup but the following code worked for me.我不知道 OP 设置出了什么问题,但以下代码对我有用。
First, the python code that generates the signature of "Hello world"
:首先,生成"Hello world"
签名的 python 代码:
from Cryptodome.Signature import PKCS1_v1_5
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
import base64
def sign(message: str, private_key_str: str) -> str:
priv_key = RSA.importKey(private_key_str)
h = SHA256.new(message.encode('utf-8'))
signature = PKCS1_v1_5.new(priv_key).sign(h)
result = base64.b64encode(signature).decode()
return result
And now the Java code that verifies it:现在验证它的 Java 代码:
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
...
...
public static boolean verify(String message, String b64Sig, byte[] pubkey_spki) throws GeneralSecurityException {
var pubKey = (PublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pubkey_spki));
var verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(pubKey);
verifier.update(message.getBytes(StandardCharsets.UTF_8));
return verifier.verify(Base64.getDecoder().decode(b64Sig));
}
Perhaps the trickiest part of this is specifying the correct padding scheme in each language/library.也许其中最棘手的部分是在每种语言/库中指定正确的填充方案。 These signatures use the scheme identified as RSASSA-PKCS1-v1_5 in the PKCS#1 RFC 8017 .这些签名使用PKCS#1 RFC 8017中标识为RSASSA-PKCS1-v1_5的方案。 On the python side this is accomplished by providing the SHA256 hash object to the PKCS1_v1_5 signature object. In Java it is perhaps a little more straightforward in that you ask for Signature
object that implements the RSA algorithm with SHA256 as the hash function, but still have to know that this is RSASSA-PKCS1-v1_5 and not some other possibility in RFC 8017. On the python side this is accomplished by providing the SHA256 hash object to the PKCS1_v1_5 signature object. In Java it is perhaps a little more straightforward in that you ask for Signature
object that implements the RSA algorithm with SHA256 as the hash function, but still have知道这是 RSASSA-PKCS1-v1_5 而不是 RFC 8017 中的其他可能性。
I think if one is not already something of an expert then understanding that these magic choices in python and Java produce compatible code is going to be difficult.我认为,如果一个人还不是专家,那么理解 python 和 Java 中的这些神奇选择会产生兼容代码将会很困难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.