APP国密改造已进入尾声,最近一次是埋点库里埋点数据的加解密,需改造成国密。
业务代码合入主工程代码时,运行APP挂掉了。
提示如下错误信息:
2022-08-01 09:50:01.738 15234-15234/com.maomao.test.activity E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.maomao.test.activity:push, PID: 15234
java.lang.RuntimeException: Unable to create application com.maomao.test.activity.tool.MyApp: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:No System TLS
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7409)
at android.app.ActivityThread.access$2400(ActivityThread.java:251)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:No System TLS
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:104)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110)
at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393)
at android.app.ActivityThread.access$2400(ActivityThread.java:251)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.lang.AssertionError: No System TLS
at okhttp3.internal.Util.assertionError(Util.java:504)
at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:296)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468)
at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138)
at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33)
at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165)
at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23)
at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144)
at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110)
at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393)
at android.app.ActivityThread.access$2400(ActivityThread.java:251)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.security.KeyManagementException: java.security.KeyStoreException: BKS not found
at com.android.org.conscrypt.SSLParametersImpl.createDefaultX509KeyManager(SSLParametersImpl.java:539)
at com.android.org.conscrypt.SSLParametersImpl.getDefaultX509KeyManager(SSLParametersImpl.java:520)
at com.android.org.conscrypt.SSLParametersImpl.<init>(SSLParametersImpl.java:128)
at com.android.org.conscrypt.OpenSSLContextImpl.engineInit(OpenSSLContextImpl.java:111)
at javax.net.ssl.SSLContext.init(SSLContext.java:326)
at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:293)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468)
at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138)
at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33)
at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165)
at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23)
at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144)
at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110)
at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393)
at android.app.ActivityThread.access$2400(ActivityThread.java:251)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.security.KeyStoreException: BKS not found
at java.security.KeyStore.getInstance(KeyStore.java:890)
at com.android.org.conscrypt.KeyManagerFactoryImpl.engineInit(KeyManagerFactoryImpl.java:63)
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:272)
at com.android.org.conscrypt.SSLParametersImpl.createDefaultX509KeyManager(SSLParametersImpl.java:528)
at com.android.org.conscrypt.SSLParametersImpl.getDefaultX509KeyManager(SSLParametersImpl.java:520)
at com.android.org.conscrypt.SSLParametersImpl.<init>(SSLParametersImpl.java:128)
at com.android.org.conscrypt.OpenSSLContextImpl.engineInit(OpenSSLContextImpl.java:111)
at javax.net.ssl.SSLContext.init(SSLContext.java:326)
at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:293)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123)
at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468)
at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138)
at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33)
at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165)
at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23)
at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144)
at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99)
at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110)
at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393)
at android.app.ActivityThread.access$2400(ActivityThread.java:251)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.security.NoSuchAlgorithmException: BKS KeyStore not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.security.Security.getImpl(Security.java:628)
2022-08-01 09:50:01.738 15234-15234/com.maomao.test.activity E/AndroidRuntime: at java.security.KeyStore.getInstance(KeyStore.java:887)
看到问题一脸懵,国密改造并没有改网络请求相关的代码。
而且本地数据库,密码加密都改造完上线了,最后埋点改造出了问题,不知从何查起;
此时我的畏难情绪达到顶点,发愁,无从下手。
经过几个日夜的情绪斗争,终于决定正视问题,解决它!
问题排查思路历程
(一)
首先“百度”了一下报错信息“java.lang.AssertionError: No System TLS
”和“java.security.KeyStoreException: BKS not found
”。
全网几乎没有答案,唯一一个匹配的问题,也是没有答案的。
最后在这几个博客文章中找到启发:
- https://www.it1352.com/980912.html
- https://www.thinbug.com/q/6866447
- https://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#ProviderInstalling
但是这些文章并没有解决我的问题。
(二)
然后我尝试打印出问题时的providerList里面有哪些内容。
发现我添加的代码没有生效。
添加provider代码如下:
static {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Log.i("sys", "运行环境没有BouncyCastleProvider");
Security.addProvider(new BouncyCastleProvider());
}
}
我在方法触发之前和触发之后都分别打印了一下所有的provider:
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
}
//此处调用static代码块
providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "getProviders after provider:" + provider.getName());
}
打印的日志如下:
getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
getProviders after provider:AndroidNSSP
getProviders after provider:AndroidOpenSSL
getProviders after provider:CertPathProvider
getProviders after provider:AndroidKeyStoreBCWorkaround
getProviders after provider:HarmonyJSSE
getProviders after provider:AndroidKeyStore
有两个发现。
- 一个是android自带了
BouncyCastleProvider
,版本是1.61 - 第二个是我执行的
Security.addProvider(new BouncyCastleProvider());
代码没有生效。
网上找到一篇关于setProvider不生效的帖子:
https://www.cnblogs.com/zhangyy3/p/13672261.html
于是我怀疑是我BC库的jar包没有签名导致给Java设置Security的值无法验证,导致插入失败。
jar包文件签名步骤:Java/Android :Jar包签名
原本是想签名一下jar包再继续验证,但是签名路程坎坷,不方便拿到签名文件,所以这条路走不通。
然后又发现另一个疑点:我的BC库版本比Android自带的BC库版本低。
有可能是低版本无法覆盖高版本的BC库,导致插入失败。
解决版本问题需要把BC库源码下载下来,改一下BouncyCastleProvider.java
的name,起一个不叫“BC”的名字。就不会与系统BC库冲突。
(这个方案是领导想出来的,他觉得非常有把握。我认为风险很高,手动编译源码,不知道会有多少坑等着我……)
这个方案或许能解决问题,但是如果Java在Security.addProvider
时需要验证签名,改了也是白搭。
(三)
后面,转念一想:既然我可以改BouncyCastleProvider.java
里的源码,为啥不自己自定义一个Provider,然后add进去试试呢?如果自定义的Provider能插入进去,说明Java在Security.addProvider
时不验证签名,可以尝试改源码的方案。
于是我将BouncyCastleProvider.java
源码拷贝了一份,将里面的
public static final String PROVIDER_NAME = "BC";
改成了
public static final String PROVIDER_NAME = "BCTEMP";
然后测试代码改成了
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
}
Security.addProvider(new BouncyCastleProvider());
providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "getProviders after provider:" + provider.getName());
}
打印日志如下:
getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
getProviders after provider:AndroidNSSP
getProviders after provider:AndroidOpenSSL
getProviders after provider:CertPathProvider
getProviders after provider:AndroidKeyStoreBCWorkaround
getProviders after provider:HarmonyJSSE
getProviders after provider:AndroidKeyStore
getProviders after provider:BCTEMP
验证结果:名叫“BCTEMP
”的provider添加成功了。
这个结果说明:
Security.addProvider
不校验签名,任何继承Provider
的类都可以被添加进去;
这就更加无法解释为啥我之前的Security.addProvider
没有添加成功了。
- 第一个签名的疑问已经打消,因为自定义代码没有签名也能生效;
- 第二个版本低的问题,因为我是先删除后添加,理论上不存在版本覆盖的问题。
(四)
于是我又多打印了一些日志。在下面这段代码
static {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Log.i("sys", "运行环境没有BouncyCastleProvider");
Security.addProvider(new BouncyCastleProvider());
}
}
的前前后后也加了日志:
static {
Log.e("e", "static current Thread name:" + Thread.currentThread().getName() + ",Thread id:" + Thread.currentThread().getName());
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "static getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
}
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Log.e("e", "static getProviders remove provider result:" + Security.getProvider(BouncyCastleProvider.PROVIDER_NAME));
providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "static getProviders remove provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
}
int result = Security.addProvider(new BouncyCastleProvider());
Log.e("e", "static getProviders add provider result:" + result);
providers = Security.getProviders();
for (Provider provider : providers) {
Log.e("e", "static getProviders add provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
}
}
打印结果:
getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
static getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
static getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
static getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
static getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
static getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
static getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
static getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
getProviders after provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders after provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders after provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders after provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders after provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders after provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders after provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
static getProviders after provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
static getProviders after provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
static getProviders after provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
static getProviders after provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
static getProviders after provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
static getProviders after provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
static getProviders after provider name:BC,version:1.58,className:com.org.bouncycastle.jce.provider.BouncyCastleProvider
验证发现:
provider name:BC,version:1.58
已经被添加进去了。getProviders after provider
的日志在static getProviders after provider
之前打印。
这个结果说明:
static{}
代码块执行Security.addProvider
,是在在调用者调用完static{}
代码块代码之后。static{}
代码块执行和调用者代码执行不在同一个线程
导致了1的结果。
随后我添打印了一下各自当前线程,得到了证实,确实不在同一线程。
问题根本原因是:
static{}
代码块是在子线程执行的(因为埋点调用国密加解密是在子线程执行),而调用方是主线程(埋点调用方和okhttp初始化同在主线程)。在执行Security.removeProvider
之后,又进入了主线程中执行okhttp初始化。而okhttp初始化需要用到名叫“BC”的Provider,此时“BC”的Provider正好已经被删除了,新的Security.addProvider
还没添加进来,导致okhttp初始化时报错:No System TLS / BKS not found
解决方案
找到问题原因就好办了。现在问题演变成了多线程同步问题,如何保证在okhttp初始化之前,“BC”Provider已经初始化好了。
所以最后解决方案是:把static{}
代码块执行的时机,放在埋点库调用国密加解密、和okhttp初始化之前,并且在主线程执行。
这样,可以保证埋点库调用国密加解密开子线程之前,static{}
代码块已经执行过了。利用线程之间数据共享和static{}
代码块只会执行一次的原理,后面执行埋点库开子线程调用国密加解密时,static{}
代码块已经执行过,且无需再执行static{}
代码块就能进行后面的操作。
小结
这是一次超乎想象的难题,问题起因毫无头绪,排查非常困难,而且影响面极大,应用初始化的时候就crash了。
我有时候会逃避问题,见到这么棘手的问题,要是百度不能解决,我就很想放弃。但是这是个大问题,埋点库必须要上线,国密也必须要上线,APP坚决不能崩溃!
所以只能硬着头皮上了。
回过头来发现:在毫无头绪的时候,多打印日志观察现象,是一个好的解决思路。
逃避不能解决任何问题。最后还是要回到问题本身,正视问题,观察问题原因,不断怀疑提问,然后顺着自己的提问判断假设是否成立,总结出问题的真正原因所在。
这次的经验对我非常重要。我才发现“畏难心理”是一个非常不利于帮助解决问题的情绪。再大的问题,只要你慢慢跟他耗,总会有解决的一天,但是如果什么都不做,那就会毫无进展。
勇敢毛毛,不怕困难。
冲呀~
你好,最近在做在Android里面做基于国密的双向https认证,用的也是okhttp,请问有参考示例,向您学习
是国密证书认证还是协同签名?国密证书双向认证需要一个可用的国密证书这个需要找机构去签。协同签名也需要找三方机构完成协同签名认证。
你好!最近要在Android工程中加入国密加解密,一点头绪没有,问一下有android SM2和SM4的加解密方法吗?谢谢
基于bouncycastle开源库做封装,这个库提供了对应的国密加解密解决方案。