Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用java加密文件,用密钥aes在openssl中解密_Java_File_Encryption_Openssl_Aes - Fatal编程技术网

用java加密文件,用密钥aes在openssl中解密

用java加密文件,用密钥aes在openssl中解密,java,file,encryption,openssl,aes,Java,File,Encryption,Openssl,Aes,我引用了一个用java加密文件的链接(加密文件创建成功) 稍后我想用openssl解密它。 我试过下面的命令,但似乎都不起作用。 请建议使用正确的命令在openssl中解密 openssl aes-256-cbc -d -in sample.crypt -out sample.txt -k testpass 显示“坏幻数” 显示“读取输入文件时出错” 这是我的加密java代码: import java.io.FileInputStream; import java.io.FileOutputS

我引用了一个用java加密文件的链接(加密文件创建成功)

稍后我想用openssl解密它。 我试过下面的命令,但似乎都不起作用。 请建议使用正确的命令在openssl中解密

openssl aes-256-cbc -d -in sample.crypt -out sample.txt -k testpass
显示“坏幻数”

显示“读取输入文件时出错”

这是我的加密java代码:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;

public class EncryptTest {

    private static final String SALTED_STR = "Salted__";
    private static final byte[] SALTED_MAGIC = SALTED_STR.getBytes(US_ASCII);
    static String password = "testpass";

    public static String encryptfile(Context context, String path, int category) {
            try {
                FileInputStream fis = new FileInputStream(path);
                FileOutputStream fos = new FileOutputStream(path.concat(".crypt"));
                final byte[] pass = password.getBytes(US_ASCII);
                final byte[] salt = (new SecureRandom()).generateSeed(8);

                final byte[] passAndSalt = array_concat(pass, salt);
                byte[] hash = new byte[0];
                byte[] keyAndIv = new byte[0];
                for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
                    final byte[] hashData = array_concat(hash, passAndSalt);
                    final MessageDigest md = MessageDigest.getInstance("MD5");
                    hash = md.digest(hashData);
                    keyAndIv = array_concat(keyAndIv, hash);
                }

                final byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
                final byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
                final SecretKeySpec key = new SecretKeySpec(keyValue, "AES");

                final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
                CipherOutputStream cos = new CipherOutputStream(fos, cipher);
                int b;
                byte[] d = new byte[8];
                while ((b = fis.read(d)) != -1) {
                    cos.write(d, 0, b);
                }
                cos.flush();
                cos.close();
                fis.close();
                Log.e(TAG, "encrypt done " + path);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            }
        }

        return path;
}   
import java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.security.invalidalgorithParameterException;
导入java.security.InvalidKeyException;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入java.security.SecureRandom;
导入java.util.array;
导入java.util.Base64;
导入javax.crypto.Cipher;
导入javax.crypto.CipherOutputStream;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.SecretKeySpec;
导入静态java.nio.charset.StandardCharsets.US_ASCII;
导入静态java.nio.charset.StandardCharsets.UTF_8;
公共类加密测试{
私有静态最终字符串SALTED\u STR=“SALTED\uuu”;
私有静态最终字节[]SALTED_MAGIC=SALTED_STR.getBytes(US_ASCII);
静态字符串password=“testpass”;
公共静态字符串加密文件(上下文上下文、字符串路径、int类别){
试一试{
FileInputStream fis=新的FileInputStream(路径);
FileOutputStream fos=新的FileOutputStream(path.concat(“.crypt”);
final byte[]pass=password.getBytes(US\U ASCII);
最后一个字节[]salt=(new SecureRandom()).generateSeed(8);
最后一个字节[]passAndSalt=数组_concat(pass,salt);
字节[]哈希=新字节[0];
字节[]keyAndIv=新字节[0];
对于(int i=0;i<3&&keyAndIv.length<48;i++){
最后一个字节[]hashData=array_concat(hash,passAndSalt);
final MessageDigest md=MessageDigest.getInstance(“MD5”);
hash=md.digest(hashData);
keyAndIv=数组_concat(keyAndIv,散列);
}
最后一个字节[]keyValue=Arrays.copyOfRange(keyAndIv,0,32);
最后一个字节[]iv=Arrays.copyOfRange(keyAndIv,32,48);
最终SecretKeySpec密钥=新SecretKeySpec(keyValue,“AES”);
final Cipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,密钥,新的IvParameterSpec(iv));
CipherOutputStream cos=新的CipherOutputStream(fos,密码);
int b;
字节[]d=新字节[8];
而((b=fis.read(d))!=-1){
cos.write(d,0,b);
}
cos.flush();
cos.close();
fis.close();
Log.e(标记“加密完成”+路径);
}捕获(IOE异常){
e、 printStackTrace();
}捕获(无算法异常){
e、 printStackTrace();
}捕获(无此填充例外){
e、 printStackTrace();
}捕获(InvalidKeyException | InvalidAlgorithmParameterException e){
e、 printStackTrace();
}
}
返回路径;
}   

OpenSSL需要一种特殊的格式,即ASCII编码值
Salted\uuuu
,后跟8字节salt,后跟实际的密文。在发布的Java代码中,未写入第一个块(ASCII编码的
Salted___
加上salt),即必须添加该块,例如:

。。。
最后一个字节[]salt=(new SecureRandom()).generateSeed(8);
fos.write(盐渍魔术);
写作(salt);
...
通过此更改,密文包含使用OpenSSL解密所需的信息和格式

应该注意的是,OpenSSL在早期版本中使用MD5作为默认摘要,而在上一版本v1.1.0中使用SHA256。因此,对于后面的版本,必须在OpenSSL语句中添加一个
-md5
(对于早期版本,它是可选的)

两条已发布的OpenSSL语句都成功地解密了在我的计算机上使用(修改过的)Java代码创建的密文(在第二条语句中,必须删除
-base64
选项,因为Java代码不对密文进行base64编码):

openssl aes-256-cbc-d-in-sample.crypt-out-sample.txt-k testpass-md md5
openssl enc-aes-256-cbc-pass:testpass-d-p-in sample.crypt-out sample.txt-md md5
还应该提到的是,OpenSSL应用该函数来派生密钥和IV。该函数不是标准函数,被认为是相对不安全的,请参见。OpenSSL的新版本会生成相应的警告(警告:使用了不推荐的密钥派生)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;

public class EncryptTest {

    private static final String SALTED_STR = "Salted__";
    private static final byte[] SALTED_MAGIC = SALTED_STR.getBytes(US_ASCII);
    static String password = "testpass";

    public static String encryptfile(Context context, String path, int category) {
            try {
                FileInputStream fis = new FileInputStream(path);
                FileOutputStream fos = new FileOutputStream(path.concat(".crypt"));
                final byte[] pass = password.getBytes(US_ASCII);
                final byte[] salt = (new SecureRandom()).generateSeed(8);

                final byte[] passAndSalt = array_concat(pass, salt);
                byte[] hash = new byte[0];
                byte[] keyAndIv = new byte[0];
                for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
                    final byte[] hashData = array_concat(hash, passAndSalt);
                    final MessageDigest md = MessageDigest.getInstance("MD5");
                    hash = md.digest(hashData);
                    keyAndIv = array_concat(keyAndIv, hash);
                }

                final byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
                final byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
                final SecretKeySpec key = new SecretKeySpec(keyValue, "AES");

                final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
                CipherOutputStream cos = new CipherOutputStream(fos, cipher);
                int b;
                byte[] d = new byte[8];
                while ((b = fis.read(d)) != -1) {
                    cos.write(d, 0, b);
                }
                cos.flush();
                cos.close();
                fis.close();
                Log.e(TAG, "encrypt done " + path);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            }
        }

        return path;
}