我正在尝试创建一个加密/解密的应用程序,当我使用没有填充的密码模式时,它正常工作。使用填充,块的数量是不可预测的,我无法找到问题的根源。
我使用以下代码进行测试:
private static final int KEY_LEN = 16;
private static final String ENCRYPTION_ALGO = "AES";
private static final String HASHING_ALGO = "SHA-256";
private static final String CIPHER_MODE = "AES/CFB/PKCS5Padding";
private static final String ENCODING = "UTF-8";
static private byte[] initVector;
static private SecretKey key;
static Cipher cipher;
private static SecretKey generateKey(byte[] password) {
MessageDigest md = MessageDigest.getInstance(HASHING_ALGO);
byte[] hashedKey = md.digest(password);
return new SecretKeySpec(hashedKey, 0, KEY_LEN, ENCRYPTION_ALGO);
}
public static byte[] getIV() {
return initVector;
}
public static void setup(String password)
{
key = generateKey(password.getBytes(ENCODING));
cipher = Cipher.getInstance (CIPHER_MODE);
cipher.init (Cipher.ENCRYPT_MODE, key);
AlgorithmParameters params = cipher.getParameters ();
initVector = params.getParameterSpec (IvParameterSpec.class).getIV();
}
public static void setup(String password, byte[] iv)
{
key = generateKey(password.getBytes(ENCODING));
cipher = Cipher.getInstance (CIPHER_MODE);
// define init vector that was used for encryption
cipher.init (Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
}
private static byte[] crypt(byte[] plaintext, boolean hasNext)
if (hasNext) {
return cipher.update(plaintext);
}else {
return cipher.doFinal(plaintext);
}
}
public static void main(String [] args)
{
try {
File input = new File ("input.txt");
File eoutput = new File ("output.enc");
File doutput = new File ("decrypted.txt");
FileInputStream fin = new FileInputStream(input);
FileOutputStream fout = new FileOutputStream (eoutput);
byte [] buffer = new byte [32];
int nBytes;
//encrypt
setup("password");
while ((nBytes = fin.read(buffer))!=-1) {
byte[] cyphertext;
if (nBytes < buffer.length) {
byte[] trimbuffer = new byte [nBytes];
System.arraycopy(buffer, 0, trimbuffer, 0, nBytes);
cyphertext = crypt(trimbuffer, false);
}else {
cyphertext = crypt(buffer, true);
}
fout.write(cyphertext);
}
fin.close();
fout.close();
FileInputStream fin2 = new FileInputStream(eoutput);
FileOutputStream fout2 = new FileOutputStream (doutput);
byte[] iv = getIV();
// decrypt
setup("password",iv);
while ((nBytes = fin2.read(buffer))!=-1) {
byte[] plaintext;
if (nBytes < buffer.length) {
byte[] trimbuffer = new byte [nBytes];
System.arraycopy(buffer, 0, trimbuffer, 0, nBytes);
plaintext = crypt(trimbuffer, false);
}else {
plaintext = crypt(buffer, true);
}
fout2.write(plaintext);
}
fin2.close();
fout2.close();
}
我忘了提到问题似乎在解密方面。
答案 0 :(得分:1)
经过大量测试后我才发现问题。问题是,当我读取文件并且最后一个块具有完全相同的缓冲区大小时,我总是调用crypt(buffer,true)来执行cipher.doFinal()的cipher.update()