使用openssl aes 256 cbc对加密文件进行Java解密 [英] Java decryption of an encrypted file with openssl aes 256 cbc

查看:546
本文介绍了使用openssl aes 256 cbc对加密文件进行Java解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试几天来在java中解密一个使用openssl加密的消息。该邮件已使用以下命令加密:



openssl enc -e -aes-256-cbc -kfile $ file.key -in toto -out toto.enc。 / p>

文件file.key包含256位的对称密钥。命令中没有指定盐,但文件以Salted__开头。这是我编码的类,尝试解密该文件,但不可能得到任何东西,即使删除文件的16个字符,即:Salted__ +盐加密。我明白openssl是默认的。当我尝试解密时,与加密的文本相关的异常被抛出。



有人能帮我吗?轨道 ?一个想法?



非常感谢。



代码:

  public class Java {

private static SecretKey key = null;
private static Cipher cipher = null;

public static void main(String [] args)throws Exception
{
String filename = RESOURCES_DIR +toto.enc;

byte [] key = Base64.decode(2AxIw + / AzDBj83OILV9GDpOs + izDFJEhD6pve / IPsN9 =);
SecretKeySpec secretKey = new SecretKeySpec(key,AES);
cipher = Cipher.getInstance(AES);

cipher.init(Cipher.DECRYPT_MODE,secretKey);
byte [] test = Base64.decode(readFile(filename));
byte [] decryptedBytes = cipher.doFinal(test);
String decryptptedText = new String(decryptedBytes,UTF8);

System.out.println(解密后:+ decryptptedText);
}

public final static String RESOURCES_DIR =C:/ Users / toto / Desktop /;

static String readFile(String filename)throws FileNotFoundException,IOException {
FileReader fr;
BufferedReader br;

fr = new FileReader(new File(filename));
br = new BufferedReader(fr);
String str;
String res =;
while((str = br.readLine())!= null){
res + = str;
}
return res;
}
}

错误:

 线程main中的异常javax.crypto.BadPaddingException:给定最终块未正确填充
在com.sun.crypto.provider.CipherCore.doFinal (CipherCore.java:811)
在com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
在com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java :313)
在javax.crypto.Cipher.doFinal(Cipher.java:2131)
在deciphertodeploytest6.Java.main(Java.java:52)


解决方案

不,file.key不包含密钥。 openssl enc -kfile 读取不是密钥的密码,而是用于导出密钥,还有IV适用时,在这里);请参见手册页。默认情况下,这个关键派生使用随机盐,而由于08年,默认哈希取决于您没有声明的OpenSSL版本。
另外,Java中的Cipher.getInstance(AES)另外,根据需要,默认为ECB,而不是CBC。 (它也默认为PKCS5填充,它与OpenSSL匹配,即使在技术上它应该称为PKCS7而不是PKCS5。)



要在Java中匹配PBKDF(和您可以使用BouncyCastle或相当于OpenSSL的 EVP_BytesToKey 的代码,由 openssl enc 使用。看到dupe或近似的问题:

Java相当于OpenSSL AES CBC加密

如何使用java解码使用openssl aes-128-cbc编码的字符串?

如何用-nosalt参数解密AES加密文件

如何使用openssl命令加密的Java中的文件解密使用AES?

,我尝试在规范的 https://crypto.stackexchange.com/questions/3298/is-there-as tandard-for-openssl-interoperable-aes-encryption /#35614


I have been trying for several days to decrypt in java a message encrypted with openssl. The message was encrypted with the following command:

openssl enc -e -aes-256-cbc -kfile $ file.key -in toto -out toto.enc.

The file file.key contains the symmetric key of 256 bits. No salt has been specified in the command and yet the file begins with Salted__. Here is the class that I coded to try to decrypt the file but impossible to get anything even by removing the 16 characters of the file namely the: Salted__ + the salt encrypted. I understood that openssl did it by default. When I try to decipher, an exception is thrown in relation to the encrypted text.

Could someone help me? a track ? an idea ?

Thank you very much.

The code :

  public class Java {

       private static SecretKey key = null;         
       private static Cipher cipher = null;

       public static void main(String[] args) throws Exception
       {
          String filename = RESOURCES_DIR + "toto.enc";

          byte[] key = Base64.decode("2AxIw+/AzDBj83OILV9GDpOs+izDFJEhD6pve/IPsN9=");
          SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
          cipher = Cipher.getInstance("AES");

          cipher.init(Cipher.DECRYPT_MODE, secretKey);
          byte[] test = Base64.decode(readFile(filename));
          byte[] decryptedBytes = cipher.doFinal(test);
          String decryptedText = new String(decryptedBytes, "UTF8");

          System.out.println("After decryption: " + decryptedText);
       }

        public final static String RESOURCES_DIR = "C:/Users/toto/Desktop/";

        static String readFile(String filename) throws FileNotFoundException, IOException {
            FileReader fr;
            BufferedReader br;

            fr = new FileReader(new File(filename));
            br = new BufferedReader(fr);
            String str;
            String res = "";
            while ((str = br.readLine()) != null) {
                res += str;
            }
            return res;
        }
    }

The error :

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:2131)
    at deciphertodeploytest6.Java.main(Java.java:52)

解决方案

No, file.key does not contain the key. openssl enc -kfile reads a password which is NOT the key but is used to derive the key and also IV (when applicable, and it is here); see the man page. This key derivation uses random salt by default, and since 2016-08 the default hash depends on OpenSSL version which you didn't state. Also, Cipher.getInstance("AES") in Java defaults to ECB not CBC as you need. (It also defaults to 'PKCS5' padding, which does match OpenSSL, even though technically it should be called PKCS7 not PKCS5.)

To match in Java the PBKDF (and thus key and IV) used by openssl enc you can either use BouncyCastle or code the equivalent of OpenSSL's EVP_BytesToKey; see dupe or near-dupe Qs:
Java equivalent of an OpenSSL AES CBC encryption
How to decode a string encoded with openssl aes-128-cbc using java?
How to decrypt AES encrypted file with '-nosalt' param
How to decrypt file in Java encrypted with openssl command using AES?
and my attempt at canonical https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption/#35614

这篇关于使用openssl aes 256 cbc对加密文件进行Java解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆