加密无法解密java中aes256gcm加密的数据
我用OpenSSL aes-256-gcm加密了一个文件。由于命令行不支持aes-256-gcm,我已经安装了LibreSSL,我可以使用下面的命令加密文件的数据
openssl enc-aes-256-gcm-K 6161-iv 768A5C31A97D5FE9-e-in文件。输入输出文件。出去
我需要解密文件中的数据。在爪哇,我无法做到这一点
示例代码:
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
String key = "61616161616161616161616161616161";
byte[] IV = "768A5C31A97D5FE9".getBytes();
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Decryption
byte[] decryptedText = cipher.doFinal(cipherText); // for the data by reading file.out
然而,javax是一个例外。加密。AEADBadTagException:标记不匹配
# 1 楼答案
这不应该奏效。Commandline
openssl enc
不支持AEAD密码/模式,尽管早期版本的1.0.1(在补丁h下,2012-2014年)在错误地指定此类密码并默默产生错误输出时无法捕获。如果您实际使用的是LibreSSL,而不是OpenSSL,那么它似乎继承了这个问题,而没有修复它,尽管LibreSSL项目的全部要点是,他们将修复由不称职的OpenSSL人员造成的所有错误如果这是一个在OpenSSL(以及Java)中正常工作的密码,比如aes-256-ctr,那么您唯一的问题就是
openssl enc -K -iv
以十六进制(适用于shell上下文)获取它们的参数,而Java crypto是从可以处理二进制数据的代码中调用的,并期望其参数以这种形式出现。因此,您提供给OpenSSL的值实际上是16字节(128位)和8字节(64位),而不是应该的256位和128位(对于CTR;对于GCM来说,96位的IV是正确的,但正如所指出的,GCM在这里不起作用)openssl enc
会自动用(二进制)零填充-K -iv
,但Java不会。因此,您需要更像比较AES encrypt with openssl command line tool, and decrypt in Java和Blowfish encrypt in Java/Scala and decrypt in bash(后者是相反的方向,但匹配的需求是相同的)