gpt4 book ai didi

java - AES-GCM:AEADBadTagException:GCM 中的 mac 检查失败

转载 作者:搜寻专家 更新时间:2023-11-01 01:51:42 28 4
gpt4 key购买 nike

在第一次尝试实现 AES-GCM 时,我们在生成 AuthenticationTag、加密密码和 GCM mac 检查时遇到了问题,最终失败了。对于当前的实现,正在填充 tag[]byte[] encrypted 仍然为空。由于此 cipher.doFinal(data1, offset) 给出“GCM 中的 mac 检查失败”。字节数组的大小似乎存在一些问题,有人可以分享确定输出缓冲区大小的依据是什么吗?这应该分块完成吗?

任何指向 AES-GCM 实现的指针/链接都将受到高度赞赏。

以下是我们的实现:

public class GCMTest {

public static void main(String[] args) throws Exception {

//***********************************************************
//Key
byte[] key = MessageDigest.getInstance("MD5").digest("1234567890123456".getBytes("UTF-8"));//this is the random key

//Iv
SecureRandom srand = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[256];
srand.nextBytes(iv);

//Input
byte[] data="inputPlainText".getBytes();

final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * Byte.SIZE, iv);

//***********************************************************
//Encryption
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), gcmParameterSpec);

cipher.updateAAD("MyAAD".getBytes("UTF-8"));

//Encrypted output
final byte[] encrypted = new byte[cipher.getOutputSize(data.length)];
cipher.update(data, 0, data.length, encrypted, 0); //Not being updated for current data.

//Tag output
byte[] tag = new byte[cipher.getOutputSize(data.length)];
cipher.doFinal(tag, 0);


//***********************************************************
//Decryption
final SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

cipher.updateAAD("MyAAD".getBytes("UTF-8"));

//What size should be assigned to outputBuffer?
final byte[] data1 = new byte[256];

int offset = cipher.update(encrypted, 0, encrypted.length, data1, 0);
cipher.update(tag, 0, tag.length, data1, offset);
cipher.doFinal(data1, offset);

boolean isValid = checkEquals(data, data1);
System.out.println("isValid :"+isValid);
}

private static boolean checkEquals(byte[] a, byte[] b)
{
int diff = a.length ^ b.length;
for(int i = 0; i < a.length && i < b.length; i++)
diff |= a[i] ^ b[i];
return diff == 0;
}
}

它给出以下异常:

Exception in thread "main" javax.crypto.AEADBadTagException: mac check in GCM failed
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2068)
at GCMTest.main(GCMTest.java:56)

提前致谢!

最佳答案

我遇到了同样的问题。对我来说,它与编码字符串有关。我最终做了:

  1. 从要加密的字符串中获取 ASCII 字节(在您的情况下为 UTF-8)
  2. 加密字节
  3. 在 Base64 字符串中编码字节

然后解密字符串我做了:

  1. 将加密字符串解码为Base64字节
  2. 解密Base64字节
  3. 使用 ASCII 创建新字符串。

代码如下:

private String encrypt(String src) {
byte[] srcBytes = src.getBytes(StandardCharsets.US_ASCII);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);

byte[] cipherText = cipher.doFinal(srcBytes);
byte[] encryptedBytes = new byte[12 + cipherText.length];

System.arraycopy(ivBytes, 0, encryptedBytes, 0, 12);
System.arraycopy(cipherText, 0, encryptedBytes, 12, cipherText.length);

return Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
}

private String decrypt(String encryptedString) {
byte[] encryptedBytes = Base64.decode(encryptedString, Base64.DEFAULT);

cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, encryptedBytes, 0, 12));
byte[] decryptedBytes = cipher.doFinal(encryptedBytes, 12, encryptedBytes.length-12);

return Base64.encodeToString(decryptedBytes, Base64.DEFAULT);
}

我没有包括如何初始化它们的任何变量都可以从 java 文档中推断出来。我试图在 Android 中执行此操作,所以我不确定它有何不同。我发现这篇文章非常有用:Java AES/GCM/NoPadding - What is cipher.getIV() giving me?

关于java - AES-GCM:AEADBadTagException:GCM 中的 mac 检查失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27402716/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com