Wenn I try to decrypt a string, encrypted in Java I get an error: "cipher: message authentication failed".
Does java inputOffset from AESCipher.engineDoFinal(byte[] input, int inputOffset, int inputLen) meens the same as the Go nonceSize in my code?
And is "NewGCMWithNonceSize" a right one decoder for my issue?
Thanks for help. Working solution:
JAVA
public static String encryptGCM(String data) throws CryptException {
try {
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] iv = new byte[12];
random.nextBytes(iv);
log.trace("IV: {}", Arrays.toString(iv));
Key key = generateGcmKey();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] cipherText = cipher.doFinal(data.getBytes("UTF-8"));
log.trace("encrypted: {}", Arrays.toString(cipherText));
byte[] result = new byte[cipherText.length + iv.length];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(cipherText, 0, result, iv.length, cipherText.length);
log.trace("Not encoded result: {}", Arrays.toString(result));
return Base64.getEncoder().encodeToString(result);
} catch (Exception ex) {
log.error("Failure occured while encrypt text value!", ex);
throw new CryptException(data, ex);
}
}
private static Key generateGcmKey() throws CryptException {
try {
SecretKey originalKey = new SecretKeySpec(KEY.getBytes(), 0, KEY.getBytes().length, ALGO);
log.trace("Encoded key: {}", Base64.getEncoder().encodeToString(originalKey.getEncoded()));
return originalKey;
} catch (Exception ex) {
log.error("Failure occured while generate key!", ex);
throw new CryptException("Failure occured while generate key!", ex);
}
}
GO
func decode(data string) (string, error) {
ciphertext, _ := base64.StdEncoding.DecodeString(data)
key, _ := base64.URLEncoding.DecodeString(decodeKey)
c, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return "", err
}
nonceSize := 12
if len(ciphertext) < nonceSize {
return "", errors.New("ciphertext too short")
}
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
result, err := gcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", err
}
return string(result), nil
}