今天在跑Android P模拟器的时候,应用突然报错。
查看错误日志:
Caused by: java.lang.RuntimeException: java.lang.Exception: 无此算法
继续往上查,无此算法对应我自己设置的NoSuchAlgorithmException
异常
并且是在KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
时报的错
这个时候我其实很懵逼,无从下手,不知道为啥突然算法就找不到了,因为从logcat中看不到什么有效的信息,所以我在KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
这句代码前设置了一个断点,打断点调试。
error断点错误信息:
屏幕快照 2018-10-09 下午8.16.14.png
在error断点信息中,有这样一句话特别重要:
The BC provider no longer provides an implementation for KeyFactory.RSA. Please see https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html for more details.
简单翻译下:
BC提供者不再提供KeyFactory.RSA的接口。请在以下网页中查看细节(我其实也是看到这句话才反应过来是P系统适配的bug)
https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
看过上面的网站后,Google说了2件事情:
1.Provider被更改。在Android P或更高版本上,调用Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC")
或者Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC"))
会报错NoSuchAlgorithmException
,
原因是Google将弃用AndroidOpenSSL(也称为Conscrypt)提供程序复制的BC提供程序中的某些功能。
2.删除加密提供程序。也就是从P开始,Crypto提供程序就不要使用了,使用就要报错NoSuchAlgorithmException
Google也在文中说了解决办法,那就是
在P及以后的系统中使用默认的接口
原报错代码:
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
根据Google的建议,修改代码如下:
KeyFactory keyFactory;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
keyFactory = KeyFactory.getInstance("RSA"); //适配Android P及以后版本,否则报错NoSuchAlgorithmException
} else {
keyFactory = KeyFactory.getInstance("RSA", "BC");
}
问题就解决了,想要了解更多细节,大家可以查看Google的原文。
文中有什么问题,也希望大家指出。
你的点赞或赞赏,就是对我最大的鼓励,也是支持我写下去的动力,谢谢!
网友评论