I'm creating a signature in Go, for example:

//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 program receives the variable signatureString and does:

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");
boolean signatureIsValid = signature.verify(Base64.getDecoder().decode(signatureString.getBytes()));

But the signatureIsValid boolean is always false, am I doing something wrong?

1 Answers

Miguel Reis On Best Solutions

I was able to verify the signature. I'm posting here in case someone comes across this with the same question:

Signature creation in 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()
d := h.Sum(nil)
signature, err = rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, d)
if err != nil {
signatureString = base64.StdEncoding.EncodeToString(signature)

Signature verification in Java (receives signatureString): I have the public key in a .pub file and:

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.update(bytesToVerify); //bytesToVerify = bytesToSign in go
byte[] signatureDecoded = Base64.getDecoder().decode(signatureString);
boolean endorserSignatureIsValid = signature.verify(signatureDecoded);
//It is now valid

I was not able to use Base64.getDecoder() (java.lang.IllegalArgumentException: Illegal base64 character a) to decode the publicKeyPEM so I used BASE64Decoder. Not sure why.