首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >BouncyCastle GCM/CCM ArrayIndexOutOfBoundsException

BouncyCastle GCM/CCM ArrayIndexOutOfBoundsException
EN

Stack Overflow用户
提问于 2012-09-01 11:33:21
回答 1查看 3.8K关注 0票数 4

谁能给我一个在BouncyCastle中使用GCM和/或CCM模式与AES的例子?

我的代码是:

代码语言:javascript
运行
复制
SecretKeySpec   key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher          cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
byte[] block = new byte[1048576];
int i;
long st,et;

cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

BufferedInputStream bIn=new BufferedInputStream(new ProgressMonitorInputStream(null,"Encrypting ...",new FileInputStream("input")));
CipherInputStream       cIn = new CipherInputStream(bIn, cipher);
BufferedOutputStream bOut=new BufferedOutputStream(new FileOutputStream("output.enc"));

int ch;
while ((i = cIn.read(block)) != -1) {
    bOut.write(block, 0, i);
}
cIn.close();
bOut.close();

Thread.sleep(5000);

cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

BufferedInputStream fis=new BufferedInputStream(new ProgressMonitorInputStream(null,"Decrypting ...",new FileInputStream("output.enc")));
//FileInputStream fis=new FileInputStream("output.enc");
//FileOutputStream ro=new FileOutputStream("regen.plain");
BufferedOutputStream ro=new BufferedOutputStream(new FileOutputStream("regen.plain"));

CipherInputStream dcIn = new CipherInputStream(fis, cipher);

while ((i = dcIn.read(block)) != -1) {
        ro.write(block, 0, i);
}

dcIn.close();
ro.close();

但是它在GCM模式下解密时抛出这个异常(第70行是bOut.write(block, 0, i);):

代码语言:javascript
运行
复制
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.bouncycastle.crypto.modes.CCMBlockCipher.processPacket(Unknown Source)
    at org.bouncycastle.crypto.modes.CCMBlockCipher.doFinal(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at javax.crypto.CipherInputStream.a(DashoA13*..)
    at javax.crypto.CipherInputStream.read(DashoA13*..)
    at javax.crypto.CipherInputStream.read(DashoA13*..)
    at enctest.Main.main(Main.java:70)

在CCM模式下加密时出现以下异常(第70行为bOut.write(block, 0, i);):

代码语言:javascript
运行
复制
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.bouncycastle.crypto.modes.CCMBlockCipher.processPacket(Unknown Source)
    at org.bouncycastle.crypto.modes.CCMBlockCipher.doFinal(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at javax.crypto.CipherInputStream.a(DashoA13*..)
    at javax.crypto.CipherInputStream.read(DashoA13*..)
    at javax.crypto.CipherInputStream.read(DashoA13*..)
    at enctest.Main.main(Main.java:70)
EN

回答 1

Stack Overflow用户

发布于 2012-09-02 20:21:54

对于CCM模式,有一个小问题: IV的大小应该小于块大小。您的代码在以下情况下崩溃:

代码语言:javascript
运行
复制
BlockCipher ctrCipher = new SICBlockCipher(cipher);
byte[] iv = new byte[blockSize];
byte[] out;

iv[0] = (byte)(((15 - nonce.length) - 1) & 0x7);

System.arraycopy(nonce, 0, iv, 1, nonce.length);

尝试使用15字节的" IV“(IV实际上是一个现时值,但IvParameterSpec用于现时值)。

另一个问题是,当CipherInputStream无法从底层流中检索任何数据时,以及在调用close()时,都会调用cipher.doFinal()方法。请注意,CipherInputStream是一个编写得非常糟糕的类,它在抛出BadPaddingException时也会删除它-这是当标记验证失败时得到的异常(!)。您最好创建自己的基于CipherInputStream的应用程序。我已经更改了代码,以抛出特定的基于IOException的异常,而不是忽略异常,并保持boolean状态以查看doFinal()是否已在底层密码上执行。它不应该两次调用doFinal()

因此,您在这里运行的是一个Java JCE bug。我可能会把它放到Oracle bug数据库中,到目前为止,我所有的bug报告都没有被完全忽略。

测试了最新版本的OpenJDK 7和Bouncy Castle1.47 (2012-08-30或更近的版本)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12224686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档