2012-05-22 34 views
1

我在Java中编写了2个函数来加密和解密邮件。我选择了AES/CBC/PKCS7Padding作为参数。虽然加密,我的功能不能添加正确的填充(因为PKCS7Padding,它不应该加0填充我的消息),所以虽然解密我不能删除消息结尾的0。 与代码,我的问题会更加克莱尔解密时无法删除0

public static byte[] encryptStringToData(String message, String key){ 
     // transform the message from string to bytes 
     byte[] array_to_encrypt, bkey; 
     try { 
      array_to_encrypt = message.getBytes("UTF8"); 
      bkey = key.getBytes("UTF8"); 
     } catch (UnsupportedEncodingException e1) { 
      array_to_encrypt = null; 
      bkey = null; 
      return null; 
     } 

     bkey = Arrays.copyOf(bkey, 32); 
     BlockCipher engine = new AESEngine(); 
     engine.init(true, new KeyParameter(bkey, 0, 32)); 
     PKCS7Padding pad = new PKCS7Padding() ; 

     BufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine),pad); 

     c.init(true, new ParametersWithIV(new KeyParameter(bkey), new byte[16])); 

     byte[] encrypted_array = new byte[c.getOutputSize(array_to_encrypt.length)]; 

     int outputLen = c.processBytes(array_to_encrypt, 0, array_to_encrypt.length, encrypted_array, 0); 
     try 
     { 
      c.doFinal(encrypted_array, outputLen); 
     } 
     catch (CryptoException ce) 
     { 
      System.err.println(ce); 
      System.exit(1); 
     } 
     return encrypted_array; 
    } 


public static String decryptDataToString(byte[] message, String key){ 
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
     String decrypted =""; 
     try { 
      byte[] keyBytes = key.getBytes("UTF8"); 

      BlockCipher engine = new AESEngine(); 
      BufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine)); 
      keyBytes = Arrays.copyOf(keyBytes, 32); // use only first 256 bit 

      c.init(false, new ParametersWithIV(new KeyParameter(keyBytes), new byte[16])); 
      byte[] cipherText = new byte[c.getOutputSize(message.length)]; 

      int outputLen = c.processBytes(message, 0, message.length, cipherText, 0); 
      c.doFinal(cipherText, outputLen); 
      decrypted = new String(cipherText,"UTF8"); 
     } 
     catch (CryptoException ce) 
     { 
      System.err.println(ce); 
      System.exit(1); 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 

     return decrypted; 

    } 

结果(十六进制输出)

克莱尔消息:3132333435大小:5 加密的消息:561dd9f43ec183fe351776a46276991c尺寸:16 解密的消息:31323334350000000000000000000000尺寸:16

+1

为什么要填充的消息,如果你不想要?是否需要加密API?在这种情况下,请在消息的开头添加长度,以便知道要删除多少个零。 –

+0

因为我使用CBC,似乎消息需要在加密/解密密码之前填充好。 – user1408286

回答

1

您应该检查How do I get started using BouncyCastle? 的代码去除额外的字节是:

if (outputLength == output.length) { 
    return output; 
} else { 
    byte[] truncatedOutput = new byte[outputLength]; 
    System.arraycopy(
      output, 0, 
      truncatedOutput, 0, 
      outputLength 
     ); 
    return truncatedOutput; 
} 

并在代码traslates到:

outputLen += c.doFinal(cipherText, outputLen); 
if (outputLen == cipherText.length) { 
    decrypted = new String(cipherText,"UTF8"); 
} else { 
    byte[] truncatedOutput = new byte[outputLen]; 
    System.arraycopy(
      cipherText, 0, 
      truncatedOutput, 0, 
      outputLen 
     ); 
    decrypted = new String(truncatedOutput,"UTF8"); 
} 
+0

它的工作原理!我认为PKCS7Padding会自动取消键盘,但是..好吧,自己删除填充没关系。非常感谢你^^ – user1408286