Java Bouncy Castle在解密时总是抛出异常纯文本

问题描述:

我的系统中有一个进程可以接收随机纯文本或密文输入。由于性能是不是一个问题,我打算尝试解密所有进入的输入,用伪代码是这样的:Java Bouncy Castle在解密时总是抛出异常纯文本

//get the input, either a plain text, or cipher text 'in disguise' 
//ex of plain text: "some text".getBytes() 
byte[] plainText = getInput(); 
try { 

    //try to decrypt whatever it is. Using Bouncy Castle as the AES crypto engine 
    plainText = AESDecryptor.decrypt(HARDCODED_AES_KEY, plainText); 
} catch(Exception ex) { 
    ... 
} 

//do some process with the plain text 
process(plainText); 

我使用AES的加密方法。

上面的代码在很大程度上依赖于假设试图使用弹性城堡来解密纯文本将始终抛出异常。但是假设100%正确吗?当尝试解密普通的,人类可读的文本时,它总是会抛出异常吗?

在此先感谢!

简短的回答

不,你不能保证一个例外。

较长答案

接收异常的概率是依赖于所使用的填充方案。当加密库使用包含填充的算法解密数据时,它希望找到正确填充的明文。如果填充格式不正确(例如,因为输入是纯文本而不是密文),则可能会抛出异常。

如果您的解密中没有使用填充方案,并且您的输入是密码块大小的倍数(在AES的情况下为16字节),那么您的图书馆将愉快地解密明文并为您提供垃圾。


作为示例,考虑PKCS #7 padding。这会在明文末尾附加非零的字节数,其值等于填充字节数。添加足够的字节以将明文与密码的块大小对齐。例如:

12 34 56 78 9A BC DE F0 08 08 08 08 08 08 08 08 

08值是八个字节的填充与AES的块大小对准。所以,如果你解密一些明文,它可能会导致有效的填充?可能不会。但它可能,所以这是一个马虎的方式来设计你的系统。


您需要在提议的协议中添加另一个图层以指示数据是否已加密。此时指定使用的算法也可能很有用,因为这可能会使您在将来更灵活地支持其他算法。

+0

谢谢你的回答。如果你不介意,我可以作为参考的任何链接吗? – riza

+0

为了清楚地识别有效的密文,我会在OCB或GCM模式下使用加密。 – Robert

+0

@riza恐怕我没有提及手;这个答案是基于我在应用程序安全领域工作的经验。如果你在互联网上研究填充,你会理解我的观点。请注意,我也对BouncyCastle如何处理格式错误的填充做出了假设,但说实话,如果它不抛出异常(或返回'null'或其他),则不值得使用。 –