关于“javax.crypto.BadPaddingExcgException”问题的解决方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoyi52/article/details/81568390

在之前的blog中有一篇是关于找不到AES/ECB/PKCS7Padding问题的解决方案,提到过需要引入BouncyCastle组件,然后顺利解决。

后来在实际中又碰到过javax.crypto.BadPaddingExcgException异常,出现的场景是客户端通过rsa公钥对敏感字段进行加密后,服务端用私钥进行解密时报错。这个问题实际上也是跟BouncyCastle有关的。

这里对BouncyCastle是什么,为什么出现这些问题的原因做一个基本的阐述。

JCE,Java Cryptography Extension,是Java Security相关的一组包,其核心功能有:加解密、秘钥生成(对称)、MAC生成、秘钥协商。也就是说,不管是Java中的对称加密和非对称加密,都要使用到这个组件。其中,加解密功能使用的Cipher组件是JCE中最核心的组件之一。

Cipher对象通过Cipher.getInstance来生成,该方法最常用的参数有两个。第一个参数是定transformation,第二个参数是provider。如果第二个参数不指定,则使用JCE默认的provider。第一个参数必须要有,完整的模式是:algorithm/mode/padding,其中algorithm加密算法是必须的,模式和填充方式则是可选的,如果不填,就会使用provider(未指定provider则使用默认provider)的默认模式和填充方式。

因此,AES/ECB/PKCS7Padding找不到是因为默认的provider自带的是PKCS5Padding填充,不支持PKCS7Padding填充,才报错:Cannot find any provider supporting AES/ECB/PKCS7Padding,而Bouncycastle的provider支持。

Bouncycastle是一个第三方组件,扩展了JCE里面的provider,使用起来也是很简单的。只需要引入jar包并在第二个参数中指定就可以了。

但是,这个provider默认提供的模式和填充分别是None和NoPadding。这意味着如果不指定transformation参数中的模式和填充,在对明文进行加密(如rsa加密)时就没有随机数填充,每次生成的密文都是一样的(正常情况下使用填充,每次生成的密文是不一样的)。当然密文一样,从理论上来讲安全性会差一点,但是也没有大问题,问题在于解密方。解密方如果使用的不是Bouncycastle的provider默认的模式和填充,就会解密出错,也就是引出本文的问题所在。博主遇到的问题实际上更复杂一点,在未显式使用Bouncycastle的provider,也没有指定模式和填充的情况下,仍然使用了Bouncycastle的provider的默认填充方式,原因未明。

解决办法就是指定与解密方一致的算法,模式和填充。通常情况下,如果未指定模式和填充,未指定provider的情况下,jce自带的provider的默认模式和填充是ECB/PKCS5Padding,指定即可。当然也有可能是其他填充方式。

猜你喜欢

转载自blog.csdn.net/xiaoyi52/article/details/81568390