我正在做一个应该保证数据传输的项目。我使用基于密码的加密与MD5和DES来加密文件。
加密文件的类:
public class FileEncryptor {
private static String filename;
private static String password;
private static FileInputStream inFile;
private static FileOutputStream outFile;
public static String tempFilename;
public static File tempFile;
public static File encryptFile(File f, String passkey) throws Exception {
if(f.isDirectory()) {
JOptionPane.showMessageDialog(null, "file object is a directory");
return null;
}
filename = f.getPath();
password = passkey;
//Need to create a temporary file which is filled with the encrypted data.
tempFilename = filename + ".des";
tempFile = new File(tempFilename);
inFile = new FileInputStream(f);
outFile = new FileOutputStream(tempFile);
// Use PBEKeySpec to create a key based on a password.
// The password is passed as a character array.
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory sKeyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey sKey = sKeyFac.generateSecret(keySpec);
byte[] salt = new byte[8];
Random rnd = new Random();
rnd.nextBytes(salt);
int iterations = 100;
//Create the parameter spec for this salt and iteration count
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);
//Create the cipher and initiate it for encryption
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
c.init(Cipher.ENCRYPT_MODE, sKey, parameterSpec);
//Need to write the salt into the file. It is required for decryption
outFile.write(salt);
//Read the file and encrypt its bytes
byte[] input = new byte[64];
int bytesRead;
while((bytesRead = inFile.read(input)) != -1) {
byte[] output = c.update(input, 0, bytesRead);
if(output != null) { outFile.write(output); }
}
byte[] output = c.doFinal();
if(output != null) { outFile.write(output); }
//Closing the streams before exiting.
inFile.close();
outFile.flush();
outFile.close();
return tempFile;
}
}
解密文件的类:
public class FileDecryptor {
private static String filename;
private static String password;
private static FileInputStream inFile;
private static FileOutputStream outFile;
public static File decryptFile(File encryptedFile, String passkey) throws NoSuchAlgorithmException,
InvalidKeySpecException, IOException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
String encryptedfilename = encryptedFile.getPath();
password = passkey;
inFile = new FileInputStream(encryptedFile);
StringBuffer sb = new StringBuffer(encryptedfilename);
sb.reverse();
sb.delete(0, 3);
sb.reverse(); //removing the ".des" extension of the encrypted file
filename = new String(sb) + ".dec";
File decrypFile = new File(filename);
outFile = new FileOutputStream(decrypFile);
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory sKeyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey sKey = sKeyFac.generateSecret(keySpec);
// Read in the previously stored salt and set the iteration count.
byte[] salt = new byte[8];
inFile.read(salt);
int iterations = 100;
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);
//Create the cipher and initialize it for decryption.
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
c.init(Cipher.DECRYPT_MODE, sKey, parameterSpec);
byte[] input = new byte[64];
int bytesRead;
while((bytesRead = inFile.read(input)) != -1) {
byte[] output = c.update(input, 0, bytesRead);
if(output != null) {
outFile.write(output);
}
}
byte[] output = c.doFinal();
System.out.println("Decrypted the data....");
System.out.println("Wrting the data into file!!");
if(output != null) {
outFile.write(output);
}
System.out.println("Closing the streams");
inFile.close();
outFile.flush();
outFile.close();
return decrypFile;
}
}
发送逻辑:
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket cs;
OutputStream os;
FileInputStream fis;
byte[] b = new byte[6022386];
File f = new File("D:\\abc.txt");
File tempFile;
try {
tempFile = FileEncryptor.encryptFile(f, "impetus");
fis = new FileInputStream(tempFile);
ServerSocket ss = new ServerSocket(7007);
System.out.println("Created and listening...");
while(true) {
System.out.println("Incoming connection!!!!!!!!");
cs = ss.accept();
System.out.println("Client connected");
os = cs.getOutputStream();
fis.read(b);
System.out.println("Sending the encrypted data");
os.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
接收逻辑:
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("D:\\P2PFolder\\ToDec.txt.des");
FileOutputStream fos;
InputStream is;
Socket s;
int bytesRead = 0;
int current = 0;
byte[] rb = new byte[6022386];
try {
fos = new FileOutputStream(f);
System.out.println("Connecting.....");
s = new Socket(InetAddress.getLocalHost(), 7007);
System.out.println("Connected!!!");
is = s.getInputStream();
do {
System.out.println("Reading encrypted data from socket");
bytesRead = is.read(rb, current, (rb.length - current));
System.out.println(new String(rb) + bytesRead);
if(bytesRead > 0) {
current += bytesRead;
}
} while(bytesRead > -1);
fos.write(rb);
is.close();
fos.flush();
fos.close();
System.out.println("Decrypting the file");
FileDecryptor.decryptFile(f, "impetus");
} catch (Exception e) {
e.printStackTrace();
}
}
没有抛出异常,但也没有传输数据。加密部分成功完成。但转移和解密没有发生。我检查了没有加密传输文件的代码,它正在工作。加密和解密类在单独使用时也可以正常工作,无需文件传输。有人可以指出我在哪里错了。如果代码太长但我必须提供我尝试的内容,我很抱歉。
答案 0 :(得分:1)
您没有关闭服务器中的os
,因此客户端副本循环永远不会终止。
修复后,您会发现文件太大了。
fis.read(b);
System.out.println("Sending the encrypted data");
os.write(b);
问题是你的两个不同的复制过程都是错误的。在Java中复制流的规范方法如下:
byte[] buffer = new byte[8192]; // or more
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
两端使用此功能。您不需要文件大小的缓冲区,也不需要更大的缓冲区。