This question already has answers here:
Initial bytes incorrect after Java AES/CBC decryption
                            
                                (10个回答)
                            
                    
                去年关闭。
        

    

对于我的3DES加密算法,将FileInputStream和FileOutputStream转换为CipherInputStream和CipherOutputStream时遇到一些问题。有人可以指导我正确的方法吗?我最终收到错误:“ CipherInputStream无法解析为类型”。很抱歉,如果这很明显。

// author Alexander Matheakis
public static void main(String[] args) throws Exception {


    // file to be encrypted
    FileInputStream inputFile = new FileInputStream("plainfile.txt");

    // encrypted file
    FileOutputStream outputFile = new FileOutputStream("C:\\Users\\islan\\OneDrive\\Documents\\Encryptor\\plainfile.des");

    // password to encrypt the file
    String passKey = "tkfhkggovubm";


    byte[] salt = new byte[8];
    SecureRandom r = new SecureRandom();
    r.nextBytes(salt);
    PBEKeySpec pbeKeySpec = new PBEKeySpec(passKey.toCharArray());
    SecretKeyFactory secretKeyFactory = SecretKeyFactory
            .getInstance("PBEWithSHA1AndDESede");
    SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);


    PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 99999);
    Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeParameterSpec);
    outputFile.write(salt);

    byte[] input = new byte[64];
    int bytesRead;
    while ((bytesRead = inputFile.read(input)) != -1) {
        byte[] output = cipher.update(input, 0, bytesRead);
        if (output != null)
            outputFile.write(output);
    }

    byte[] output = cipher.doFinal();
    if (output != null)
        outputFile.write(output);

    inputFile.close();
    outputFile.flush();
    outputFile.close();

// author Alexander Matheakis

最佳答案

这对我有用:

public class Cypher {

    // password to encrypt the file
    private static final String passKey = "tkfhkggovubm";

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

        try (FileInputStream inputFile = new FileInputStream("plainfile.txt");
                FileOutputStream outputFile = new FileOutputStream("plainfile.des");) {

            byte[] salt = new byte[8];
            SecureRandom r = new SecureRandom();
            r.nextBytes(salt);

            outputFile.write(salt);

            PBEKeySpec pbeKeySpec = new PBEKeySpec(passKey.toCharArray());
            SecretKeyFactory secretKeyFactory = SecretKeyFactory
                    .getInstance("PBEWithSHA1AndDESede");
            SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);

            PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 99999);
            Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeParameterSpec);

            try (CipherOutputStream cis = new CipherOutputStream(outputFile, cipher);) {
                IOUtils.copy(inputFile, cis);
            }
        }

        try (FileInputStream fis = new FileInputStream("plainfile.des");
                FileOutputStream outputFile = new FileOutputStream("plainfile.txt2");) {
            byte[] salt = new byte[8];
            int saltBytes = fis.read(salt);
            if (saltBytes!=salt.length)
                throw new Exception("Huh???");

            PBEKeySpec pbeKeySpec = new PBEKeySpec(passKey.toCharArray());
            SecretKeyFactory secretKeyFactory = SecretKeyFactory
                    .getInstance("PBEWithSHA1AndDESede");
            SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);

            PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 99999);
            Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, pbeParameterSpec);

            try (CipherInputStream cis = new CipherInputStream(fis, cipher);) {
                IOUtils.copy(cis, outputFile);
            }
        }
    }
}


执行main之后,plainfile.txtplainfile.txt2相等。 plainfile.des被加密。

IOUtils.copyapache.commons-io中的一种方法,该方法在内部保留一个缓冲区并将所有字节从一个流写入另一个流。
只是将byte[] input = ...提取到方法中,再使用try-with-resources
这样可以使代码简单易读。

09-25 16:55