2013-11-10 17 views
1

我试图做一个应用程序加密/解密,并且当我使用没有填充的密码模式时它工作正常。使用填充,块的数量是不可预知的,我无法找到问题的根源。使用java来加密/解密文件使用填充时返回错误的字节数

我使用下面的代码进行测试:

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

代码似乎不完整? getIV()?密码?键? –

+0

这是为了简化,但我也会添加它 – mrafael

回答

1

我刚刚在大量测试后发现问题。问题是,当我读取文件时,最后一个块的缓冲区大小完全相同,我总是调用crypt(buffer,true)来执行cipher.dodate()的cipher.doFinal()

相关问题