在Android遇到Https一些知識點與問題

一些知識點

1.服務(wù)端生成證書文件谜叹,其實只需要利用keyTool工具生成jks后辫封,再利用KeyTool工具根據(jù)這個jks去簽發(fā)出來一個證書就可以了厉熟。具體步驟為
1. 通過keytool命令生成 jks 秘鑰文件
keytool -genkey -alias zhy_server
 -keyalg RSA -keystore zhy_server.jks
 -validity 3600 -storepass 123456

2. 通過keytool命令對 jks 進行簽發(fā)證書
keytool -export -alias zhy_server 
 -file zhy_server.cer  
 -keystore zhy_server.jks  
 -storepass 123456 

2.在加載證書的代碼中,Java平臺默認識別jks格式的證書文件溉潭,但是android平臺只識別bks格式的證書文件净响。所以你需要將'jks'轉(zhuǎn)換成bks文件,放入項目中喳瓣。
3.加載證書有兩種實現(xiàn)方式(訪問自簽名的網(wǎng)站馋贤,單向驗證):
1.你可以通過將證書文件.cer放入到項目可讀取的位置,如'assest'文件夾畏陕。
private static SSLSocketFactory getSSLSocketFactory_Certificate(Context context, String keyStoreType, int keystoreResId)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        InputStream caInput = context.getResources().openRawResource(keystoreResId);

        Certificate ca = cf.generateCertificate(caInput);

        caInput.close();

        if (keyStoreType == null || keyStoreType.length() == 0) {

            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);

        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

        SSLContext sslContext = SSLContext.getInstance("TLS");

        sslContext.init(null, wrappedTrustManagers, null);

        return sslContext.getSocketFactory();

    }

2.你可以通過keytool命令配乓,將.cer文件以.rfc格式輸出(其實也就是文本格式),然后加載這段文本就行惠毁。
keytool -printcert -rfc -file srca.cer
4.Android中 自帶的SSLContext的TrustManager無法進行工作犹芹,具體原因目前不清楚,可能是自帶的TrustManager的內(nèi)部實現(xiàn)不符合場景需求仁讨。

TrustManager的主要責任是去決定提出的認證證書應(yīng)該是可信任的。如果證書是不可信任的实昨,那么連接將會被終止

完整加載證書代碼:

 private static TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {

        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];

        return new TrustManager[]{

                new X509TrustManager() {

                    public X509Certificate[] getAcceptedIssuers() {

                        return originalTrustManager.getAcceptedIssuers();

                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {

                        try {

                            originalTrustManager.checkClientTrusted(certs, authType);

                        } catch (CertificateException e) {

                            e.printStackTrace();

                        }

                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {

                        try {

                            originalTrustManager.checkServerTrusted(certs, authType);

                        } catch (CertificateException e) {

                            e.printStackTrace();

                        }

                    }

                }

        };

    }
    /**
     *
     * @param context
     * @param keyStoreType   Keystore類型洞豁,一般都是jks 或者 bks,but荒给,Android平臺只識別bks丈挟,所以如果你要做這種
     *                       加密通信的話,你需要將你的秘鑰轉(zhuǎn)成bks格式
     * @param keystoreResId
     * @return
     * @throws CertificateException
     * @throws KeyStoreException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    private static SSLSocketFactory getSSLSocketFactory_Certificate(Context context, String keyStoreType, int keystoreResId)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        InputStream caInput = context.getResources().openRawResource(keystoreResId);

        Certificate ca = cf.generateCertificate(caInput);

        caInput.close();

        if (keyStoreType == null || keyStoreType.length() == 0) {

            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);

        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

        SSLContext sslContext = SSLContext.getInstance("TLS");

        sslContext.init(null, wrappedTrustManagers, null);

        return sslContext.getSocketFactory();

    }

5. 默認信任所有證書

上面的代碼都是在有證書的條件下志电,而如果沒有證書呢曙咽?如果跳過這個環(huán)節(jié)還保證不出錯?那么只能信任所有的證書

 client.sslSocketFactory(createSSLSocketFactory());
        client.hostnameVerifier(new TrustAllHostnameVerifier());
        
        
        
          private static class TrustAllManager implements 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];
        }
    }

    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挑辆,一起剝皮案震驚了整個濱河市例朱,隨后出現(xiàn)的幾起案子孝情,更是在濱河造成了極大的恐慌,老刑警劉巖洒嗤,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箫荡,死亡現(xiàn)場離奇詭異,居然都是意外死亡渔隶,警方通過查閱死者的電腦和手機羔挡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來间唉,“玉大人绞灼,你說我怎么就攤上這事〕室埃” “怎么了低矮?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長际跪。 經(jīng)常有香客問我商佛,道長,這世上最難降的妖魔是什么姆打? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任良姆,我火速辦了婚禮,結(jié)果婚禮上幔戏,老公的妹妹穿的比我還像新娘玛追。我一直安慰自己,他們只是感情好闲延,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布痊剖。 她就那樣靜靜地躺著,像睡著了一般垒玲。 火紅的嫁衣襯著肌膚如雪陆馁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天合愈,我揣著相機與錄音叮贩,去河邊找鬼。 笑死佛析,一個胖子當著我的面吹牛益老,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寸莫,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捺萌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了膘茎?” 一聲冷哼從身側(cè)響起桃纯,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酷誓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后慈参,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呛牲,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年驮配,在試婚紗的時候發(fā)現(xiàn)自己被綠了娘扩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡壮锻,死狀恐怖琐旁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猜绣,我是刑警寧澤灰殴,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掰邢,受9級特大地震影響牺陶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辣之,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一掰伸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧怀估,春花似錦狮鸭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至康铭,卻和暖如春惯退,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背从藤。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工催跪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呛哟。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓叠荠,卻偏偏與公主長得像匿沛,于是被迫代替她去往敵國和親扫责。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容