我正在尝试用C#解密一个使用Rijndael/CBC/PKCS7 7加密的文件。我一直有以下例外情况:
javax.crypto.BadPaddingException: pad块损坏 在org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(Unknown源代码中) 在javax.crypto.Cipher.doFinal(DashoA13 13*.) 在AESFileDecrypter.decrypt(AESFileDecrypter.java:57)
当web服务器为第一个doFinal(inpbytes)调用byte[]方法时。我猜这是密钥或IV的问题。我在我的文件系统上有加密的文件进行测试。下面的代码有什么明显的错误吗?
*keyStr编码为base64
public AESFileDecrypter(String keyStr){
try {
Security.addProvider(new BouncyCastleProvider());
convertIvParameter();
key = new sun.misc.BASE64Decoder().decodeBuffer(keyStr);
//use the passed in Base64 decoded key to create a key object
decryptKey = new SecretKeySpec(key, "AES");
//specify the encryption algorithm
decryptCipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
//make a parameter object for the initialization vector(IV)
IvParameterSpec ivs = new IvParameterSpec(_defaultIv);
//initialize the decrypter to the correct mode, key used and IV
decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey, ivs);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void convertIvParameter() {
int[] iv = new int[] {11, 190, 165, 33, 68, 88, 11, 200, 245, 35, 68, 23, 60, 24, 223, 67};
_defaultIv = new byte[16];
for(int x = 0; x < _defaultIv.length; x++) {
_defaultIv[x] = (byte)iv[x];
}
}
public void decryptUpdate(byte[] inpBytes) throws Exception {
//decrypt the byte passed in from the web server
decryptCipher.update(inpBytes);
}
public byte[] decryptFinal() throws Exception {
//decrypt the byte passed in from the web server
return decryptCipher.doFinal();
}
//sends bytes to the client for diaply
private void sendBytes(FileInputStream fis, OutputStream os)throws Exception {
//set the buffer size to send 4k segments of data
aesFileDecrypter = new AESFileDecrypter(<Insert Key string here>);
byte[] buffer = new byte[4096];
int bytes = 0, totalBytes = fis.available();
//while there is still data to be sent keep looping and write the data
//to the output stream as the buffer is filled
try {
while ((bytes = fis.read(buffer)) != -1) {
aesFileDecrypter.decryptUpdate(buffer);
//os.write(buffer, 0, bytes);
}
os.write(aesFileDecrypter.decryptFinal(), 0, totalBytes);
}
catch(Exception e) {
e.printStackTrace();
}
}发布于 2009-05-15 15:33:44
首先,为了明确起见,从下面的注释中可以看出,您不应该在每个块上调用doFinal(),因为doFinal()期望在末尾有任何填充,这显然不会出现在中间块中。要么(a)对中间数据调用update(),然后在末尾调用doFinal(),要么(b)安排将所有数据放在一个缓冲区或字节数组中,然后在整个作业批次上调用doFinal()一次。
从您发布的代码中还不清楚,这实际上就是您正在做的事情,但是应该提到它,以防万一。
如果失败,那么作为调试的第一步,我建议这两种方法中哪一种对您来说更容易:
我记得,C#有无符号字节(而Java ),所以有几个地方有空间让字节签名出现微妙的错误。
发布于 2011-07-26 02:07:00
我以前也遇到过这个问题。
当我编写一些代码来进行加密和解密时,如下所示:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sec, "AES"),new IvParameterSpec(new byte[cipher.getBlockSize()]));
byte[] encode = cipher.doFinal(data);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sec, "AES"), new IvParameterSpec(new byte[cipher.getBlockSize()]));
byte[] decode = cipher.doFinal(encode);我在加密数据时忘记了第一个IvParameterSpec(new byte[cipher.getBlockSize()]),然后我得到了一个异常"pad块损坏“,所以也许您应该检查一下加密代码。
发布于 2009-05-15 14:53:38
据我所知,AES是基于Rijndael的,但规范并不完全相同。我建议检查在C#中用于加密的密钥和块大小,以及在Java中使用的大小。(Rijndael和AES的.Net差异)。
https://stackoverflow.com/questions/868776
复制相似问题