App校验https证书
对App进行全面的安全性测试的时候,发现虽然用的https证书,但是也同时开启了允许任意http链接,导致检测的时候提示不安全
-
安卓HttpsURLConnection使用证书
//HttpsURLConnection private static void setCertificate(HttpsURLConnection connection) { InputStream caInput = null; try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); caInput = MyApplication.mContext.getAssets().open("sguClass.cer"); Certificate ca = cf.generateCertificate(caInput); String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); connection.setSSLSocketFactory(context.getSocketFactory()); connection.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }); } catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); } finally { try { caInput.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
安卓WebView使用证书
//Webview public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) { // super.onReceivedSslError(webView, sslErrorHandler, sslError);//sslErrorHandler.cancel(); // sslErrorHandler.proceed(); if (chkMySSLCNCert(sslError.getCertificate())) {{//结果应该都是false,有问题的话取消验证 sslErrorHandler.proceed(); } else { sslErrorHandler.cancel(); } // if (sslError.getPrimaryError() == android.net.http.SslError.SSL_DATE_INVALID // 日期不正确 // || sslError.getPrimaryError() == android.net.http.SslError.SSL_EXPIRED // 日期不正确 // || sslError.getPrimaryError() == android.net.http.SslError.SSL_INVALID // webview BUG // || sslError.getPrimaryError() == android.net.http.SslError.SSL_UNTRUSTED) { // 根证书丢失 // if (chkMySSLCNCert(sslError.getCertificate())) { // sslErrorHandler.proceed(); // 如果证书一致,忽略错误 // } // } } private static boolean chkMySSLCNCert(SslCertificate cert) { try { //本地证书 CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = MyApplication.mContext.getAssets().open("sguClass.cer"); Certificate ca = cf.generateCertificate(caInput); MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); byte[] caKey = sha256.digest(ca.getEncoded()); //服务端证书 Bundle bundle = SslCertificate.saveState(cert); byte[] bytes = bundle.getByteArray("x509-certificate"); Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(bytes));; byte[] certificateKey = sha256.digest(certificate.getEncoded()); Log.d("test", "chkMySSLCNCert" + "caKey:" + caKey + " certificateKey: " + certificateKey); return Arrays.equals(caKey, certificateKey); } catch (CertificateException | IOException | NoSuchAlgorithmException e) { e.printStackTrace(); } return false; }
-
iOS afnetworking添加证书
//AFNetworking AFHTTPSessionManager *manager = [[AFHTTPSessionManager manager] initWithBaseURL:[NSURL URLWithString:BASE_URL_API]]; manager.securityPolicy = [self customSecurityPolicy]; + (AFSecurityPolicy *)customSecurityPolicy { NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"sguClass" ofType:@"cer"];//证书的路径 NSData *cerData = [NSData dataWithContentsOfFile:cerPath]; AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; securityPolicy.allowInvalidCertificates = NO;//是否允许无效证书 if (cerData) { securityPolicy.pinnedCertificates = [NSSet setWithObject:cerData]; } return securityPolicy; }
-
iOS WKWebView添加证书
//WKWebview //Allow Arbitrary Loads in Web Content设置为YES防止外部http链接打不开 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { NSLog(@"didReceiveAuthenticationChallenge"); //1.信任所有证书 // if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { // NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust]; // completionHandler(NSURLSessionAuthChallengeUseCredential, credential); // } //2.比较证书内容,相同的在信任 //强限制,部分部分外部资源加载不了 SecTrustRef trust = challenge.protectionSpace.serverTrust; // 从信任链返回一个证书 SecCertificateRef serverCer= SecTrustGetCertificateAtIndex(trust, 0); // SecCertificateCopyData 返回X.509证书的DER表示 NSData *serverCerData = CFBridgingRelease(SecCertificateCopyData(serverCer)); NSString *localCerPath = [[NSBundle mainBundle] pathForResource:@"sguClass" ofType:@"cer"]; NSData *localCerData = [NSData dataWithContentsOfFile:localCerPath]; if ([serverCerData isEqualToData:localCerData]) { NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:trust]; [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); NSLog(@"服务端证书认证成功"); } else { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, NULL); NSLog(@"服务端证书认证失败"); } }
添加完证书之后,发现会有一些问题,主要是外部http资源和第三方http链接无法访问,所以有去掉了部分验证。如果项目没有用到这些内容,还是可以添加的,更安全一些。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?