繁体   English   中英

ED25519 在 Golang 中验证在 Java 中签名的有效负载失败

[英]ED25519 Verification fails in Golang for payload signed in Java

我有两个单独的应用程序,一个用 Java 编写,另一个用 golang 编写。 Java 应用程序负责生成密钥对,其中的公钥与 golang 应用程序共享。 每当需要对任何有效负载进行签名时,golang 应用程序都会向 Java 应用程序发送请求,并获得 base64 编码签名作为回报。 此签名需要使用公钥进行验证。 golang 应用中的验证总是失败。 但是,我能够在 Java 应用程序中成功验证。 如果密钥生成和有效负载签名也使用 golang 完成,则 golang 中的验证有效。

For Java, I'm using Bouncy Castle library and for golang using package https://pkg.go.dev/crypto/ed25519 .

生成密钥

Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(new Ed25519KeyGenerationParameters(new SecureRandom()));
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) asymmetricCipherKeyPair.getPrivate();
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) asymmetricCipherKeyPair.getPublic();
String privateKey = Base64.getEncoder().encodeToString(privateKey.getEncoded());
String publicKey = Base64.getEncoder().encodeToString(publicKey.getEncoded());

签名有效载荷

byte[] privateKeyContent = Base64.getDecoder().decode(privateKeyInfo);
Ed25519PrivateKeyParameters privateKeyParameters = new Ed25519PrivateKeyParameters(privateKeyContent, 0);

byte[] payload = Base64.getEncoder().encode(input.getBytes(StandardCharsets.UTF_8));
Signer signer = new Ed25519Signer();
signer.init(true, privateKeyParameters);
signer.update(payload, 0, payload.length);
byte[] signature = signer.generateSignature();
String encodedSignature = Base64.getEncoder().encodeToString(signature);

Golang 验证签名

func verifySignature(payload []byte, publicKeyStr string, signatureStr string) {
    publicKey, error := base64.StdEncoding.DecodeString(publicKeyStr)
    if error != nil {
        fmt.Println(error)
    } else {
        signature, error := base64.StdEncoding.DecodeString(signatureStr)
        if error != nil {
            fmt.Println(error)
        } else {
            isVerified := ed25519.Verify(publicKey, payload, signature)
            fmt.Println(isVerified)
        }

    }
}

Java 代码不对消息本身进行签名,而是对 Base64 编码的消息进行签名。

我怀疑您的验证失败,因为签名和验证的消息不同。 但是,这不能肯定回答,因为您没有在 Go 端发布payload的内容。

无论如何,如果在 Java 端对消息本身进行签名(通常是这种情况),则验证成功:

String input = "...";
byte[] payload = input.getBytes(StandardCharsets.UTF_8);

同样,如果使用未修改的 Java 代码,则验证成功,Go 端验证 Base64 编码消息(这将是相当不寻常的):

input := "..."
payload := []byte(base64.StdEncoding.EncodeToString([]byte(input)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM