我正在用Java创建一个应用程序,我希望允许用户使用他们选择的密码加密文件(或文件夹 - 我会压缩目录)。我目前有以下方法:
static Cipher createCipher(int mode, String password) throws Exception {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(keySpec);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update("input".getBytes());
byte[] digest = md.digest();
byte[] salt = new byte[8];
for (int i = 0; i < 8; ++i)
salt[i] = digest[i];
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(mode, key, paramSpec);
return cipher;
}
static void applyCipher(String inFile, String outFile, Cipher cipher) throws Exception {
String decryption = "";
CipherInputStream in = new CipherInputStream(new FileInputStream(inFile), cipher);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
int BUFFER_SIZE = 8;
byte[] buffer = new byte[BUFFER_SIZE];
int numRead = 0;
do {
numRead = in.read(buffer);
System.out.println(buffer + ", 0, " + numRead);
if (numRead > 0){
out.write(buffer, 0, numRead);
System.out.println(toHexString(buffer, 0, numRead));
}
} while (numRead == 8);
in.close();
out.flush();
out.close();
}
private static char[] hex_table = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
public static String toHexString(byte[] data, int offset, int length)
{
StringBuffer s = new StringBuffer(length*2);
int end = offset+length;
for (int i = offset; i < end; i++)
{
int high_nibble = (data[i] & 0xf0) >>> 4;
int low_nibble = (data[i] & 0x0f);
s.append(hex_table[high_nibble]);
s.append(hex_table[low_nibble]);
}
return s.toString();
}
但是,为了使程序更加用户友好,我希望能够在生成文件之前检查用户是否输入了正确的密码。我不想“把钥匙留在门垫下面”或完全取消安全等等 - 我只是想防止在用户输入错误的密码时产生错误的文件......
任何想法将不胜感激。如果您需要更多详情,请随时询问。
提前致谢
答案 0 :(得分:3)
您可以使用该文件保存加密密码。当用户输入密码时,您对其进行加密并检查文件中是否存在相同的加密密码。如果没有,你就不加载文件。
答案 1 :(得分:2)
使用PBKDF2WithHmacSHA1而不是PBEWithMD5AndDES。后来的用户有两种不同的过时原语。前者是现行标准。
你有两个选择
速度快但不太安全: 在加密文件的开头加上一个简短的已知值,或者在相同的密码下加密完全不同的短文件。解密此文件时,请检查已知值。
显然这很快就能奏效。它的安全性稍差,因为这意味着攻击者试图强行密码可以更快地丢弃猜测的密码:而不必查看整个文件,他们只需要检查该值。这不是一个大问题,因为您的密钥派生函数应该足够难以且它们仍然必须运行
存储加密文件的哈希值,并在解密时验证哈希值。 更安全的是,攻击者必须解密整个文件并通过它进行读取,但同样的道理,它很慢。
答案 2 :(得分:1)
我会使用AEAD模式,例如CCM或EAX。这将在文件解密时检查文件的每个块的完整性,如果密钥不正确或文件被篡改则会失败。这些模式的Bouncy Castle提供者supports both。