上一篇 提到移植 commmon-codec 包来解决加密前后端加密算法同步的问题。
接着做 android 端和服务端联调 RSA 加密算法里还是出问题了。情况是这样:
- 两端自己单独加解密,没问题。
- 两端单元测试产生的加密字符串对方都可以解密。
- 真实环境调试,android 端发送的加密字符串,服务端无法解密。
报错:
javax.crypto.BadPaddingException : Decryption error
查询,应该是两端的填充模式不同,导致服务端解密失败。
服务端用 Cipher.getInstance("RSA") 方法进行加密时,使用的 provider 是Bouncycastle Security provider,Bouncycastle Security provider 默认实现的是 “RSA/None/NoPadding” 算法,而客户端用 Cipher.getInstance("RSA") 进行解密时,使用的是 Sun 的 security provider,实现的是 “RSA/None/PKCS1Padding” 算法,所以,解密时会失败。
于是在服务端改为:
Cipher.getInstance("RSA/None/PKCS1Padding")
测试报错并不支持该算法。改为“RSA/None/NoPadding”,仍然不支持。然后在 android 模拟器调试时也发现,android 端对同样的字符串加密获得是相同的密文,这更符合 “RSA/None/NoPadding” 的效果。于是改为在 android 端获取 Cipher 时,指定算法 “RSA/None/PKCS1Padding”,联调加解密成功。
证明 android 端使用的默认填充方式是“RSA/None/NoPadding”,而服务端使用的是“RSA/None/PKCS1Padding”。和上文引用的说明正好相反。
值得注意的是:
android 端在跑 java 代码的单元测试时,每次对同样的字符串加密获得是不同的密文,而模拟器和真机调试时却一直是相同的。这里很误导人,也很费解, android 端 RSA 这里使用的完全是 java sdk,不懂为什么单元测试和模拟器运行时效果不同。
网友评论