java - java中的RSA签名消息验证失败
问题描述
我已经用 Java 中的 RSA 私钥签署了一条消息。可以使用公钥在 Java 本身中成功验证。但是,当我尝试在 Go 中验证具有相同签名的消息时,它失败了。
重现问题的步骤:
- 在java代码中使用sign方法生成签名
- 在java代码中运行验证方法
- 替换Java生成的签名字符串后运行Go测试函数
无论如何,如果我使用纯文本而不是哈希,我可以在 Java 和 Go 中成功验证(我已经在 Java 方法中注释掉了这行代码)
Java 代码
public static String sign(String plaintext, PrivateKey privateKey){
try {
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(privateKey);
byte[] hash = sha256Hash(plaintext.getBytes());
privateSignature.update(hash);
//privateSignature.update(plaintext.getBytes());
byte[] signature = privateSignature.sign();
return Base64.getEncoder().encodeToString(signature);
}catch (Exception ex){
System.out.println("Exception:"+ex.toString());
return "";
}
}
public static void verify(String plaintext, String signature, PublicKey publicKey){
try {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(publicKey);
byte[] hash = sha256Hash(plaintext.getBytes());
publicSignature.update(hash);
//publicSignature.update(plaintext.getBytes());
byte[] signatureBytes = Base64.getDecoder().decode(signature);
System.out.println("Verified:"+publicSignature.verify(signatureBytes));
}catch (Exception ex){
System.out.println("Exception:"+ex);
}
}
public static byte[] sha256Hash(byte[] content) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest(content);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.getMessage(),e);
}
}
去测试功能
func Test_sigVerify(t *testing.T) {
data := []byte("Hello World")
dig := sha256.Sum256(data)
signature := "VP8J3fGZXgHPM9wpKpW0t3mihPSM0VFFjcrZ9IjFpazQMqbKGMryz7Z7D0ufG/hOXPZrKdgtoXQ3jXmcQyvhFB+CEo5j3KsoQ5xq5pGZoaOWjjO7tRxZ2zNfwDkCY+TOKm1JB4So1/ELQU2FCowDfJDxlezPCrAgQFAD0ZkN6Omx/0Hd2HIWCRnOgYyjJvO6DPyaUvd2N+UB0JhrLxDQSi6NJS6b2VZGHANQB3Ik7FDXO5o19qmAxgrv5/ZS1wLRqn+jClFTzbXt3DBPOFHk/3P71ugU6cCkx+BRmGJyrbSgmWi/Z4zDpwy+IdWbfJCCByoaFizZp72rxrPtYqU1fA=="
publicKey, err := parsePublicKey3()
if err != nil {
fmt.Println("Public key paring error:", err)
}
b64, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
fmt.Println("Decoding error:", err)
}
verifyErr := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, dig[:], b64)
if verifyErr != nil {
fmt.Println("Verify Error:", verifyErr)
return
}
fmt.Println("successfully verified")
}
func parsePublicKey3() (*rsa.PublicKey, error) {
pString := `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlnOCGYMjRR1toSvSgWq2DB1ytz5VF5I1M7wkOksxnJhbgiEC7MnlrctEgPqQXWzzULk/StQSbwip39ZbDEr+uLC/yks2z1+8DmgZe8WR5b/6SBXV3hrPc/rWS0v+fYHkdJ2buhqhqcOfwYntu1tEk3tGyjubQDa6XobDZRHhuRF9mzw7Eld2Atf//wxiGzHylNVa+/SysozVy68ZUcn3tveYClxOEuVYIv3EEnsWnkBPu5/PHBplLr7t6IdJ86viB9hkdocYWj5TQgMccwees6fZ7MKcLeh+WryyajqFJsppvT70t4RmiABjrp1BWB4VEoA9PYwiOKEPsDD8OZOCSQIDAQAB
-----END PUBLIC KEY-----`
var err error
block, _ := pem.Decode([]byte(pString))
if block == nil {
fmt.Println("block is nil")
return nil, err
}
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
return publicKey.(*rsa.PublicKey), nil
}
解决方案
推荐阅读
- c# - 如何在代码 C# .net 5 中获取当前使用的 openapi 版本
- r - 按组在多列上汇总唯一值
- linux - 使用 at 命令(预定脚本)运行 bash 脚本不起作用
- vue.js - 将 Formstack 嵌入 Vuejs
- groovy - 如何从 groovy 元素访问 Camel 的属性 CamelLoopIndex?
- java - 我想通过 Java Rest api 在 Google Duo 上创建一个用户。遵循文档但出现错误
- colors - highlightcolor 与 monokai for atom 不同,与 sublime 文本中的不同
- c# - 缓动功能而不从 Freezable 继承?
- c# - 使用泛型和单链表(错误 CS0311)
- python - 为什么即使我在 Pipfile 中指定了版本,依赖项也会默认为最新版本?