如何在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的内容。感谢您的建议,我将在将来记住它