如何使用 BouncyCastle 解密,使用 GCM Tag 的字符串,IV 字符串和密钥字符串,所有这些都是十六进制的?
Posted
技术标签:
【中文标题】如何使用 BouncyCastle 解密,使用 GCM Tag 的字符串,IV 字符串和密钥字符串,所有这些都是十六进制的?【英文标题】:How can I decrypt using BouncyCastle, a string using a GCM Tag , IV string and Key string, all of them in HEX? 【发布时间】:2022-01-17 13:26:08 【问题描述】:我正在尝试使用 GCM 模式和 HEX 输入从 CyberChef 复制 AES-Decrypt 功能。 操作截图:
到目前为止,我已经编写了以下代码:
package decryption;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
public class Main
public static final int GCM_TAG_LENGTH = 32;
public static void main(String[] args) throws Exception
String IV = "9092d522e11120919fce8492";
String input = "90fab0";
String GCMTag = "02883e111ad6f79cd53674b5f833abab";
String key = "8cda92dcb3283da821daa275359642c7a05d60a4badb5769618193a930c1cdec";
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), 0, key.getBytes(StandardCharsets.UTF_8).length, "AES");
System.out.println(decrypt(input.getBytes(StandardCharsets.UTF_8), secretKey, IV.getBytes(StandardCharsets.UTF_8)));
public static String decrypt(byte[] cipherText, SecretKeySpec key, byte[] IV) throws Exception
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
cipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec);
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
对于我得到的上述代码:
Exception in thread "main" org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$InvalidKeyOrParametersException: Invalid value for MAC size: 256
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(Unknown Source)
at java.base/javax.crypto.Cipher.init(Cipher.java:1442)
at java.base/javax.crypto.Cipher.init(Cipher.java:1375)
at decryption.Main.decrypt(Main.java:29)
at decryption.Main.main(Main.java:19)
我很确定我还差得很远,但我没有找到任何关于如何将 GCM 标签用作输入的文章/教程。
【问题讨论】:
【参考方案1】:这里使用的GCM标签长度不是32,而是16字节。
此外,BC 提供者期望密文和标签以串联形式(密文|标签)。
您必须对密钥、IV、密文和标签进行十六进制解码。由于您正在运行 BouncyCastle,您可以使用 org.bouncycastle.util.encoders.Hex.decode(...)
。
总体:
import org.bouncycastle.util.encoders.Hex;
...
public static final int GCM_TAG_LENGTH = 16;
...
SecretKeySpec secretKey = new SecretKeySpec(Hex.decode(key), "AES");
System.out.println(decrypt(Hex.decode(input + GCMTag), secretKey, Hex.decode(IV))); // 985
从您的代码中不清楚您是否使用静态 IV/nonce。如果是这样,您应该意识到对 GCM 使用静态 IV/nonce 是一个严重的问题,s。例如here. 相反,对于每次加密,都会生成一个随机(非秘密)IV/nonce,与密文(和标签)连接,并一起发送到解密端,解密端可以根据已知的 IV/nonce 分离 IV/nonce大小(GCM 为 12 字节)。
SunJCE 提供程序也支持 AES/GCM(至少从 Java 8 开始,例如here),因此您可能不需要 BouncyCastle。对于十六进制解码,您可以使用this post 的解决方案。从 Java 17 开始,有一个内置支持。
【讨论】:
非常感谢@Topaco!以上是关于如何使用 BouncyCastle 解密,使用 GCM Tag 的字符串,IV 字符串和密钥字符串,所有这些都是十六进制的?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 BouncyCastle 解密,使用 GCM Tag 的字符串,IV 字符串和密钥字符串,所有这些都是十六进制的?
为 RSACryptoProvider 和 BouncyCastle 生成密钥/加密/解密