【问题标题】:Using Java to verify signature created in Golang使用 Java 验证在 Golang 中创建的签名
【发布时间】:2019-05-18 09:58:42
【问题描述】:

我在 Go 中创建一个签名,例如:

//I'm reading a file with -----BEGIN RSA PRIVATE KEY-----
privateKeyPem := strings.Replace(privateKeyString, `\n`, "\n", -1) //file has '/n' instead of break lines for dev purposes
block, _ := pem.Decode([]byte(privateKeyPem))
key, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
hashedString := sha256.Sum256([]byte(stringTosign))
signature, err = rsa.SignPKCS1v15(rand.Reader, key, crypto2.SHA256, hashedString[:])
signatureString := base64.StdEncoding.EncodeToString(signature)

Java 程序接收变量 signatureString 并执行:

byte[] keyBytes = Files.readAllBytes(Paths.get("./golangSignerPubKey.der"));
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey =  kf.generatePublic(spec);
Signature signature = Signature.getInstance("SHA256withRSA", "BC");
signature.initVerify(publicKey);
signature.update(stringUnsigned.getBytes());
boolean signatureIsValid = signature.verify(Base64.getDecoder().decode(signatureString.getBytes()));

但是 signatureIsValid 布尔值总是假的,我做错了什么吗?

【问题讨论】:

  • 您是否已验证您可以在 Go 中对其进行解码?这将使查找错误更容易。
  • 是的,我在创建签名后验证它是否有效(验证成功):clientCertEndorserSignToVerify, err := base64.StdEncoding.DecodeString(signatureSTring) errVerify := rsa。验证PKCS1v15(publicKey.(*rsa.PublicKey), crypto2.SHA256, hashedString, signatureString)

标签: java go digital-signature x509


【解决方案1】:

我能够验证签名。我在这里发帖以防有人遇到同样的问题:

Go 中的签名创建:

bytesToSign := []byte (stringToSign)
block, err8 := pem.Decode([]byte(privateKeyPem)) //-----BEGIN RSA PRIVATE KEY----
if err8 != nil {
    logger.Debugf("Error trying decode endorser private key")
}
key, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
h := sha256.New()
h.Write(bytesToSign)
d := h.Sum(nil)
signature, err = rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, d)
if err != nil {
    panic(err)
}
signatureString = base64.StdEncoding.EncodeToString(signature)

Java 中的签名验证(接收签名字符串): 我在 .pub 文件中有公钥,并且:

byte[] keyBytes = Files.readAllBytes(Paths.get("./public_key.pub"));
String temp = new String(keyBytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("\n-----END PUBLIC KEY-----", "");
BASE64Decoder b64= new BASE64Decoder();
byte[] decoded = b64.decodeBuffer(publicKeyPEM);
X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
publicKey = kf.generatePublic(spec);
Signature signature = Signature.getInstance("SHA256withRSA", "BC");
signature.initVerify(publicKey);
signature.update(bytesToVerify); //bytesToVerify = bytesToSign in go
byte[] signatureDecoded = Base64.getDecoder().decode(signatureString);
boolean endorserSignatureIsValid = signature.verify(signatureDecoded);
//It is now valid

我无法使用 Base64.getDecoder() (java.lang.IllegalArgumentException: Illegal base64 character a) 来解码 publicKeyPEM,所以我使用了 BASE64Decoder。不知道为什么。

【讨论】:

  • PEM 文件(如 MIME,但不是 XML 或 JSON)将 base64 分成几行。 Java8+ Base64.getDecoder() 用于带有 no 换行符的“基本”base64;对于 MIME 之类的换行符,请使用 Base64.getMimeDecoder(),如 in the javadoc 所述。或者在解码之前根据您的系统或文件删除所有\n\r\n
【解决方案2】:

我昨天也遇到了这个问题,终于解决了。

可能对其他人有帮助:https://github.com/xioxu/signature_in_multiple_lang

【讨论】:

    猜你喜欢
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多