如何在Java中用3DES(Triple-DES)加密和解密文件

如何在Java中用3DES(Triple-DES)加密和解密文件,java,encryption,3des,Java,Encryption,3des,这是我所拥有的,但我无法破译文件。 我找不到一个可以让我破译的逻辑。 我不知道它是否加密正确,因为我无法破译它 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException;

这是我所拥有的,但我无法破译文件。 我找不到一个可以让我破译的逻辑。 我不知道它是否加密正确,因为我无法破译它

 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
 import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.DESedeKeySpec;
 import javax.crypto.spec.IvParameterSpec;

 public class TestEncryptor {

     public static void main(String... args) {
         try {
             String KEY_STRING = "asdasdasd";
             byte[] key = getEnKey(KEY_STRING);
             String pFilePath = "D:\\fileTest.png";
             String pFilePathEncryp = "D:\\fileTestEncryp.png";
             byte[] archivoDecrypt = encryptFile(pFilePath, key);

             try (FileOutputStream fos = new FileOutputStream(pFilePathEncryp)) {
                 fos.write(archivoDecrypt);
             }
         } catch (Exception e) {
             e.printStackTrace();
         }

     }

     public static byte[] encryptFile(String pFilePath, byte[] pKey) throws GeneralSecurityException, IOException {
         File file = new File(pFilePath);
         long length = file.length();
         InputStream is = new FileInputStream(file);

         // You cannot create an array using a long type.
         // It needs to be an int type.
         // Before converting to an int type, check
         // to ensure that file is not larger than Integer.MAX_VALUE.
         if (length > Integer.MAX_VALUE) {
             // File is too large
         }

         // Create the byte array to hold the data
         byte[] bytes = new byte[(int) length];

         // Read in the bytes
         int offset = 0;
         int numRead = 0;
         while (offset < bytes.length
                 && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
             offset += numRead;
         }

         // Close the input stream and return bytes
         is.close();

         // Ensure all the bytes have been read in
         if (offset < bytes.length) {

             throw new IOException("Could not completely read file " + file.getName());
         }

         SecretKeyFactory lDESedeKeyFactory = SecretKeyFactory.getInstance("DESede");
         SecretKey kA = lDESedeKeyFactory.generateSecret(new DESedeKeySpec(pKey));

         IvParameterSpec lIVSpec = new IvParameterSpec(new byte[8]);
         Cipher desedeCBCCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");

         desedeCBCCipher.init(Cipher.ENCRYPT_MODE, kA, lIVSpec);
 //        desedeCBCCipher.init(Cipher.DECRYPT_MODE, kA, lIVSpec);
         byte[] encrypted = desedeCBCCipher.doFinal(bytes);

         return encrypted;
     }

     private static byte[] getEnKey(String spKey) {
         byte[] desKey = null;
         try {
             byte[] desKey1 = md5(spKey);
             desKey = new byte[24];
             int i = 0;
             while (i < desKey1.length && i < 24) {
                 desKey[i] = desKey1[i];
                 i++;
             }
             if (i < 24) {
                 desKey[i] = 0;
                 i++;
             }
         } catch (Exception e) {
             e.printStackTrace();
         }

         return desKey;
     }

     private static byte[] md5(String strSrc) {
         byte[] returnByte = null;
         try {
             MessageDigest md5 = MessageDigest.getInstance("MD5");
             returnByte = md5.digest(strSrc.getBytes("GBK"));
         } catch (Exception e) {
             e.printStackTrace();
         }
         return returnByte;
     }
 }
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.security.GeneralSecurityException;
导入java.security.MessageDigest;
导入javax.crypto.Cipher;
导入javax.crypto.SecretKey;
导入javax.crypto.SecretKeyFactory;
导入javax.crypto.spec.DESedeKeySpec;
导入javax.crypto.spec.IvParameterSpec;
公共类测试员{
公共静态void main(字符串…参数){
试一试{
字符串键\u String=“asdasdasd”;
字节[]key=getEnKey(key\u字符串);
字符串pFilePath=“D:\\fileTest.png”;
字符串pFilePathEncryp=“D:\\fileTestEncryp.png”;
字节[]archivoDecrypt=加密文件(pFilePath,密钥);
try(FileOutputStream fos=newfileoutputstream(pFilePathEncryp)){
fos.write(归档文件);
}
}捕获(例外e){
e、 printStackTrace();
}
}
公共静态字节[]加密文件(字符串pFilePath,字节[]pKey)引发GeneralSecurityException,IOException{
文件=新文件(pFilePath);
long length=file.length();
InputStream is=新文件InputStream(文件);
//不能使用长类型创建数组。
//它必须是int类型。
//在转换为int类型之前,请检查
//以确保文件不大于Integer.MAX_值。
if(长度>整数最大值){
//文件太大
}
//创建字节数组以保存数据
字节[]字节=新字节[(int)长度];
//读入字节
整数偏移=0;
int numRead=0;
while(偏移量=0){
偏移量+=numRead;
}
//关闭输入流并返回字节
is.close();
//确保已读入所有字节
if(偏移量<字节长度){
抛出新IOException(“无法完全读取文件”+file.getName());
}
SecretKeyFactory lDESedeKeyFactory=SecretKeyFactory.getInstance(“DESede”);
SecretKey kA=lDESedeKeyFactory.generateSecret(新的DESedeKeySpec(pKey));
IvParameterSpec lIVSpec=新的IvParameterSpec(新字节[8]);
Cipher desedecbcipher=Cipher.getInstance(“DESede/CBC/PKCS5Padding”);
desedecbcipher.init(Cipher.ENCRYPT_模式,kA,lIVSpec);
//desedecbcipher.init(Cipher.DECRYPT_模式,kA,lIVSpec);
byte[]encrypted=desedeCBCCipher.doFinal(字节);
返回加密;
}
私有静态字节[]getEnKey(字符串spKey){
字节[]desKey=null;
试一试{
字节[]desKey1=md5(spKey);
desKey=新字节[24];
int i=0;
而(i
如果其他人需要,这就是解决方案

    try {
        File inputFileNAme = new File(origen);
        FileInputStream fileInputStream = new FileInputStream(inputFileNAme);
        FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
        SecretKey secretKey = getKey(keyString);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        ObjectInputStream objectInputStream = new ObjectInputStream(new CipherInputStream(fileInputStream, cipher));
        System.out.println(objectInputStream.available());
        fileOutputStream.write((byte[]) objectInputStream.readObject());
        fileOutputStream.flush();
        fileOutputStream.close();
        fileInputStream.close();
        objectInputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

解密语言非常相似,只需使用
desedeCBCCipher.init(Cipher.DECRYPT_MODE,kA,lIVSpec)谢谢你的帮助。你可以看看我的加密。如果IV被重用,CBC是不安全的(所以全零IV是个坏主意)。您的
getEncKey
不是从密码派生密钥的安全方法,请使用PBKDF2。将3DES的最后一个键设置为全零(MD5始终输出16字节)是一个非常糟糕的主意,因为它可能会将DES的安全性降低到80位甚至更低。请不要在StackOverflow上发布仅代码的答案。我不知道你从哪里得到的
objectInputStream
,或者你为什么需要它来解密文件。请遵循Java流媒体教程,阅读例如关于try-with-resources的内容。感谢您的建议,我将在将来记住它