Tag mismatch error in AES-256-GCM Decryption using Java(使用 Java 的 AES-256-GCM 解密中的标签不匹配错误)
问题描述
我有以下用 Javascript 编写的函数,用于使用 aes-256-gcm 进行加密:
I have the following function written in Javascript for encryption using aes-256-gcm:
encrypt: function (text, masterkey){
try {
// random initialization vector
var iv = crypto.randomBytes(12);
// random salt
var salt = crypto.randomBytes(64);
// derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
// a large number of iterations. It may can replaced by HKDF
var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');
// AES 256 GCM Mode
var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
// encrypt the given text
var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
// extract the auth tag
var tag = cipher.getAuthTag();
// generate output
return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');
}catch(e){
}
// error
return null;
}
上述函数的加密文本使用以下函数成功解密回来:
The encrypted text by the above function is successfully decrypted back using the following function:
decrypt: function (data, masterkey){
try {
// base64 decoding
var bData = new Buffer(data, 'base64');
var salt = bData.slice(0, 64);
var iv = bData.slice(64, 76);
var tag = bData.slice(76, 92);
var text = bData.slice(92);
// derive key using; 32 byte key length
var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');
// AES 256 GCM Mode
var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(tag);
// decrypt the given text
var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');
return decrypted;
}catch(e){
}
// error
return null;
}
现在,我需要一个 Java 中的解密方法,它相当于上面的 Javascript 解密函数.以下是我为解密编写的Java代码:
Now, I need a method in Java for decryption which is the equivalent of the above Javascript decrypt function. Following is the Java code I have written for decryption:
public void decrypt(byte[] nkb, String crKey){
//nkb is byte array formed by Base64 decoding of 'data' variable in the Javascript code
//crKey corresponds to the 'masterkey' variable
byte[] salt = Arrays.copyOfRange(nkb, 0, 64);
byte[] iv = Arrays.copyOfRange(nkb, 64, 76);
byte[] tag = Arrays.copyOfRange(nkb, 76, 92);
byte[] text = Arrays.copyOfRange(nkb, 92, nkb.length);
PBEKeySpec ks = new PBEKeySpec(crKey.toCharArray(), salt, iterations, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
SecretKey pbeKey = skf.generateSecret(ks);
byte[] decrypted = decrypt(iv, pbeKey.getEncoded(), text, tag);
}
public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes, byte[] tagBytes)
throws java.io.UnsupportedEncodingException,
NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeyException,
InvalidAlgorithmParameterException,
IllegalBlockSizeException,
BadPaddingException,
NoSuchProviderException {
GCMParameterSpec ivSpec = new GCMParameterSpec(tagBytes.length*Byte.SIZE, ivBytes);
SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
return cipher.doFinal(textBytes); //getting tag mismatch error here
}
正如我在上面的代码中所评论的,我在最后一行得到了一个标签不匹配错误.如果能帮助我找出我做错了什么,我将不胜感激.
As I have commented in the above code, I get a Tag mismatch error in the last line. I would appreciate some help in finding out what I am doing wrong.
我在这行代码中有错误:
I have error in this line code:
cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec)
java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:93)
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:82)
推荐答案
您需要将标签提供给 Java GCM 代码,以便它可以检查消息是否真实.Java API 期望将标签附加到密文中.更改代码以执行此操作的最简单方法是替换该行
You need to provide the tag to the Java GCM code so that it can check that the message is authentic. The Java API expects the tag to be appended to the ciphertext. The simplest way to change your code to do that would be to replace the line
return cipher.doFinal(textBytes);
两行:
cipher.update(textBytes);
return cipher.doFinal(tagBytes);
这篇关于使用 Java 的 AES-256-GCM 解密中的标签不匹配错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Java 的 AES-256-GCM 解密中的标签不匹配错误


基础教程推荐
- 在 Java 中创建日期的正确方法是什么? 2022-01-01
- 验证是否调用了所有 getter 方法 2022-01-01
- 大摇大摆的枚举 2022-01-01
- 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
- 从 python 访问 JVM 2022-01-01
- Java 实例变量在两个语句中声明和初始化 2022-01-01
- Java Swing计时器未清除 2022-01-01
- 多个组件的复杂布局 2022-01-01
- 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
- 不推荐使用 Api 注释的描述 2022-01-01