Reputation: 1629
I've two separate applications one written in Java and the other in golang. Java application is responsible to generate keypair out of which public key is shared with golang app. Whenever, there's a need to sign any payload golang app sends a request to Java app and gets the base64 encoded signature in return. This signature needs to be verified using the public key. The verification always fails in golang app. However, I'm able to successfully verify in Java app. Verification in golang works if key generation and signing the payload is also done using golang.
For Java, I'm using Bouncy Castle library and for golang using package https://pkg.go.dev/crypto/ed25519.
Generate Key
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());
Sign Payload
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 Verify Signature
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)
}
}
}
Upvotes: 0
Views: 972
Reputation: 49121
The Java code does not sign the message itself, but the Base64 encoded message.
I suspect that verification fails for you because signed and verified message are different. However, this cannot be answered for sure, since you did not post the content of payload
on the Go side.
In any case, verification is successful if on the Java side the message itself is signed (which is usually the case):
String input = "...";
byte[] payload = input.getBytes(StandardCharsets.UTF_8);
Similarly, verification is successful if, with unmodified Java code, the Go side verifies the Base64 encoded message (which would be rather unusual):
input := "..."
payload := []byte(base64.StdEncoding.EncodeToString([]byte(input)))
Upvotes: 2