新四季網

ssl協議安全基礎(安卓下安全通信)

2023-05-05 20:59:30

安卓系統BKS證書的使用一、 概述

手機默認內置了主流的根證書,一般在使用OkHttp時,使用本地根證書進行校驗,項目不需要內置CA根證書。

手機可以在設置停用某個根證書,這時與一些伺服器通信,就會報ssl異常。用瀏覽器打開網頁時,會提示 未授信的網站。

當使用自己製作的證書的時候,可以把證書放到項目裡打包到APK中。

二、keytool支持BKS的設置

安卓通用使用的是BKS格式的證書。但JDK默認情況下不支持BKS證書格式,如果要使用BKS需要進行以下操作:

下載 org.bouncycastle.jce.provider.BouncyCastleProvider 包,網址:https://www.bouncycastle.org把下載的 bcprov-ext-jdk15to18-166.jar , bcprov-jdk15to18-166.jar 放到 %JAVA_HOME%/jre/lib/ext 下。(我也不知道為啥我下載有兩個包)修改%JAVA_HOME%/jre/lib/security/java.security文件我的配置是這樣的:

jdk.TLS.disabledAlgorithms=security.provider.1=sun.security.provider.Sunsecurity.provider.2=sun.security.rsa.SunRsaSignsecurity.provider.3=sun.security.ec.SunECsecurity.provider.4=com.sun.net.ssl.internal.ssl.Providersecurity.provider.5=com.sun.crypto.provider.SunJCEsecurity.provider.6=sun.security.jgss.SunProvidersecurity.provider.7=com.sun.security.sasl.Providersecurity.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRIsecurity.provider.9=sun.security.smartcardio.SunPCSCsecurity.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

三、cer轉換為bks格式1. 格式轉換命令

keytool -importcert -trustcacerts -keystore cNetty.bks -file cNetty.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider# 按提示輸入密鑰庫指令keytool -importcert -trustcacerts -keystore sNetty.bks -file sNetty.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider# 按提示輸入密鑰庫指令

2. 導入信任證書庫

這時要把證書導入對方信任證書的倉庫中,使用命令:

keytool -import -alias securenettyclient_bks -file cNetty.cer -storepass 你的storepass密碼 -keystore sNetty.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProviderkeytool -import -alias securenettyservice_bks -file sNetty.cer -storepass 你的storepass密碼 -keystore cNetty.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider

3. 查看bks證書

# 查看證書鏈keytool -list -rfc -keystore cNetty.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass 你的storepass證書# 驗證BKSkeytool -list -v -storetype BKS -keystore sNetty.bks

四、java socket使用bks證書的核心客戶端代碼

以下代碼客戶端支持使用jks和bks兩種格式、支持windows和android端使用,可以用在Netty框架:

import lombok.extern.slf4j.Slf4j;import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManagerFactory;import java.io.IOException;import java.io.InputStream;import java.nio.file.Files;import java.nio.file.Paths;import java.security.*;import java.security.cert.CertificateException;/** * 加密通訊,獲取SSLContext的方法 * @author Cade */@Slf4jpublic final class SecureNettySslContextfactory { private static final String PROTOCOL = "TLS"; private static final String FILE_JKS ="jks"; private static final String KEYSTORE_BKS ="BKS"; private static final String KEYSTORE_JKS ="JKS"; /** * 伺服器安全上下文 */ private static SSLContext SERVER_CONTEXT; /** * 客戶端安全上下文 */ private static SSLContext CLIENT_CONTEXT; /** * * @param pkPath pkPath * @param caPath caPath * @param jksPass jksPass * @param storePass storePass * @return SSL上下文 */ public static SSLContext getClientContext(String pkPath,String caPath,String jksPass,String storePass){ if(CLIENT_CONTEXT!=null) { return CLIENT_CONTEXT; } final String; KeyManagerFactory kmf; TrustManagerFactory tf; KeyStore ks; KeyStore tks ; try { if(caPath.contains(FILE_JKS)) { ks = KeyStore.getInstance(KEYSTORE_JKS); tks = KeyStore.getInstance(KEYSTORE_JKS); }else{ Security.addProvider(new BouncyCastleProvider); ks = KeyStore.getInstance(KEYSTORE_BKS); tks = KeyStore.getInstance(KEYSTORE_BKS); } // 如果是安卓系統,讀取資源的方式有所不同 if (osAndroid.equals(Constants.OS)) { try (InputStream in = Constants.class.getResourceAsStream(pkPath)) { ks.load(in, jksPass.toCharArray); } try(InputStream in = Constants.class.getResourceAsStream(caPath)){ tks.load(in, jksPass.toCharArray); } } else { try (InputStream stream = Files.newInputStream(Paths.get(pkPath))) { ks.load(stream, jksPass.toCharArray); } try (InputStream stream = Files.newInputStream(Paths.get(caPath))) { tks.load(stream, jksPass.toCharArray); } } if(log.isInfoEnabled) { log.info(TrustManagerFactory.getDefaultAlgorithm); } kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, storePass.toCharArray); tf = TrustManagerFactory.getInstance("SunX509"); tf.init(tks); CLIENT_CONTEXT = SSLContext.getInstance(PROTOCOL); //初始化此上下文 //參數一:認證的密鑰 參數二:對等信任認證 參數三:偽隨機數生成器 。 由於單向認證,服務端不用驗證客戶端,所以第二個參數為null CLIENT_CONTEXT.init(kmf.getKeyManagers, tf.getTrustManagers, null); }catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | KeyManagementException e){ if(log.isErrorEnabled){ log.error(e.toString); } } return CLIENT_CONTEXT; }}

代碼裡Constants類是自定義的常量類。

五、OKHttp使用證書

bks一般可以放在assets下。

public class MyOkhttpClient { private static MyOkhttpClient singleton; public static OkHttpClient getInstance { if (singleton == null) { synchronized (CBOkhttpClient.class) { if (singleton == null) { OkHttpClient.Builder builder = new OkHttpClient.newBuilder; builder.connectTimeout(50000, TimeUnit.MILLISECONDS); builder.writeTimeout(50000, TimeUnit.MILLISECONDS); builder.readTimeout(50000, TimeUnit.MILLISECONDS); try { SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm); KeyStore trustStore = KeyStore.getInstance("BKS"); InputStream ksinstream = CBFramework.getApplication.getResources.openRawResource(R.raw.cbframework_trustcerts); trustStore.load(ksinstream, "".toCharArray); ksinstream.close; trustManagerFactory.init(trustStore); sslContext.init(null, trustManagerFactory.getTrustManagers, new SecureRandom); builder.sslSocketFactory(sslContext.getSocketFactory, new X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers { return new X509Certificate[0]; } }); } catch (Exception e) { Log.e(e); } singleton = builder.build; } } } return singleton; }}

,
同类文章
葬禮的夢想

葬禮的夢想

夢見葬禮,我得到了這個夢想,五個要素的五個要素,水火只好,主要名字在外面,職業生涯良好,一切都應該對待他人治療誠意,由於小,吉利的冬天夢想,秋天的夢是不吉利的
找到手機是什麼意思?

找到手機是什麼意思?

找到手機是什麼意思?五次選舉的五個要素是兩名士兵的跡象。與他溝通很好。這是非常財富,它擅長運作,職業是仙人的標誌。單身男人有這個夢想,主要生活可以有人幫忙
我不怎麼想?

我不怎麼想?

我做了什麼意味著看到米飯烹飪?我得到了這個夢想,五線的主要土壤,但是Tu Ke水是錢的跡象,職業生涯更加真誠。他真誠地誠實。這是豐富的,這是夏瑞的巨星
夢想你的意思是什麼?

夢想你的意思是什麼?

你是什​​麼意思夢想的夢想?夢想,主要木材的五個要素,水的跡象,主營業務,主營業務,案子應該抓住魅力,不能疏忽,春天夢想的吉利夢想夏天的夢想不幸。詢問學者夢想
拯救夢想

拯救夢想

拯救夢想什麼意思?你夢想著拯救人嗎?拯救人們的夢想有一個現實,也有夢想的主觀想像力,請參閱週宮官方網站拯救人民夢想的詳細解釋。夢想著敵人被拯救出來
2022愛方向和生日是在[質量個性]中

2022愛方向和生日是在[質量個性]中

[救生員]有人說,在出生88天之前,胎兒已經知道哪天的出生,如何有優質的個性,將走在什麼樣的愛情之旅,將與生活生活有什么生活。今天
夢想切割剪裁

夢想切割剪裁

夢想切割剪裁什麼意思?你夢想切你的手是好的嗎?夢想切割手工切割手有一個真正的影響和反應,也有夢想的主觀想像力。請參閱官方網站夢想的細節,以削減手
夢想著親人死了

夢想著親人死了

夢想著親人死了什麼意思?你夢想夢想你的親人死嗎?夢想有一個現實的影響和反應,還有夢想的主觀想像力,請參閱夢想世界夢想死亡的親屬的詳細解釋
夢想搶劫

夢想搶劫

夢想搶劫什麼意思?你夢想搶劫嗎?夢想著搶劫有一個現實的影響和反應,也有夢想的主觀想像力,請參閱週恭吉夢官方網站的詳細解釋。夢想搶劫
夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂什麼意思?你夢想缺乏異常藥物嗎?夢想缺乏現實世界的影響和現實,還有夢想的主觀想像,請看官方網站的夢想組織缺乏異常藥物。我覺得有些東西缺失了