簡體   English   中英

android 調用中的密鑰庫版本錯誤

[英]Wrong version of keystore on android call

我想提出一個 https 請求。

我使用 bouncycastle 生成這樣的密鑰庫:

keytool -importcert -trustcacerts -alias ludevCA -file lu_dev_cert.crt -keypass mypass -keystore keystore.bks -storepass mypass -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk15on-146.jar  

並且 keylist 命令返回正確的值。

但是當我這樣做時:

KeyStore ks = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(R.raw.keystore);  
ks.load(in, "mypass".toCharArray());

我有一個錯誤:

wrong version of keystore

我嘗試使用幾個版本的 bouncycast,但結果是一樣的。 我也嘗試定義 keysize 1024,但沒有任何變化。

有任何想法嗎 ?

看看它Android:信任 SSL 證書

  -storetype BKS
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider
  -providerpath /path/to/bouncycastle.jar

並在創建密鑰庫時使用此版本: 此處找到的1.46 版

可以幫助...

您需要將密鑰庫的類型從 BKS 更改為 BKS-v1(BKS-v1 是 BKS 的舊版本)。 因為 BKS 版本已更改為here

還有另一種解決方案,這要容易得多:

  1. 使用 Portecle:
  1. 您可以使用KeyStore Explorer

新文件將使用 BKS-v1 進行編碼,並且不再顯示錯誤。 要更改 KeyStore 類型,請打開 KeyStore Explorer 並轉到Tools -> Change KeyStore Type ,然后保存文件。

筆記:
Android 適用於不同的 BKS 版本:例如,API 15 需要 BKS-1,而 API 23 需要 BKS,因此您可能需要將這兩個文件都放在您的應用程序中。

您可以使用此代碼根據 API 級別在它們之間切換:

int bks_version;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    bks_version = R.raw.publickey; //The BKS file
} else {
    bks_version = R.raw.publickey_v1; //The BKS (v-1) file
}
KeyStore ks = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(bks_version);  
ks.load(in, "mypass".toCharArray());

最后我在 Windows 下使用了一個圖形編輯器(KeyStore Explorer)並且它正在工作。

可能是 Java/Mac 版本問題導致的錯誤

解決方案在這里,能夠刪除版本問題

為 android 客戶端創建 BKS 文件

創建 BKS 文件所需的軟件安裝詳細信息:

從鏈接http://keystore-explorer.sourceforge.net/下載 Keystore Explorer 軟件

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html下載 UnlimitedJCEPolicyJDK7

解壓 zip 並將 US_export_policy 和 local_policy 復制到您的 C:/programes file/java/jre7/lib/security 文件夾。

安裝密鑰庫資源管理器軟件。

生成 BKS 文件的步驟:(需要 CA 文件、證書文件、密鑰文件和 .P12 iePKCS 文件(如果可用)。

1) 使用密鑰庫軟件使用 CA .crt 文件創建信任文件。

腳步:

打開軟件
轉到文件->新建->從向導中選擇.BKS 導入CA證書文件轉到工具->導入可信證書->選擇CA .crt文件->輸入密碼->(如果證書是自簽名會拋出異常)強制導入文件。

4. 以 .bks 擴展名保存文件。

2) 使用密鑰庫軟件使用 .P12 文件創建密鑰文件

腳步

打開軟件 Go File->New->從向導中選擇 .BKS

導入>p12 文件 Go Tool -> 導入密鑰對 -> 從向導中選擇 PKCS #12 -> 輸入文件和瀏覽文件的解密密碼 -> 輸入 alise 名稱(如果要更改其他可以保持原樣) -> 輸入新密碼

使用 .bks 擴展名保存文件。

3) 使用密鑰庫軟件創建密鑰文件,如果 .P12 不是可用文件

腳步

打開軟件

轉到文件->新建->從向導中選擇 .BKS 導入 >p12 文件轉到工具 -> 導入密鑰對 -> 從向導中選擇 OpenSSL -> 文件的未選中解密密碼,瀏覽 .key 和 .crt(證書文件不是 CA)文件 -> 輸入 alise 名稱(如果要更改其他可以保持原樣) -> 輸入新密碼

使用 .bks 擴展名保存文件。

將兩個文件復制到 res/raw 文件夾中(兩個 BKS 文件都是必需的)。

代碼:

 static final String ENABLED_CIPHERS[] = {
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
    "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
    "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
    "TLS_RSA_WITH_AES_256_CBC_SHA",
    "TLS_RSA_WITH_AES_128_CBC_SHA",
    "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
    "SSL_RSA_WITH_RC4_128_SHA",
    "SSL_RSA_WITH_RC4_128_MD5",
};
// put this in a place where it can be reused
static final String ENABLED_PROTOCOLS[] = {
        "TLSv1.2", "TLSv1.1", "TLSv1"
    };

   private void sslCon()
    {
        try {
                             // setup truststore to provide trust for the server certificate
              // load truststore certificate
            InputStream trustStoresIs = getResources().openRawResource(R.raw.client_ca);
            String trustStoreType = KeyStore.getDefaultType();
            KeyStore trustStore = KeyStore.getInstance(trustStoreType);
            trustStore.load(trustStoresIs, "spsoft_123".toCharArray());
            //keyStore.setCertificateEntry("ca", ca);

            // initialize trust manager factory with the read truststore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(trustStore);

            // setup client certificate
            // load client certificate
            InputStream keyStoreStream = getResources().openRawResource(R.raw.client_cert_key);
            KeyStore keyStore = null;
            keyStore = KeyStore.getInstance("BKS");
            keyStore.load(keyStoreStream, "your password".toCharArray());

            KeyManagerFactory keyManagerFactory = null;
            keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, "your password".toCharArray());

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);

            SSLSocketFactory sslsocketfactory = (SSLSocketFactory)context.getSocketFactory();
            InetAddress serverAddr = InetAddress.getByName("192.168.11.104");
            sslSocket = (SSLSocket) sslsocketfactory.createSocket(serverAddr, 5212);
            //String[] ciphers = sslSocket.getEnabledCipherSuites();
            sslSocket.setEnabledCipherSuites(ENABLED_CIPHERS);
            // put this right before setEnabledCipherSuites()!
            //sslSocket.setEnabledProtocols(ENABLED_PROTOCOLS);
            //InputStream inputStream =  sslSocket.getInputStream();
            OutputStream out = sslSocket.getOutputStream();

            Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_SHORT).show();
            sslSocket.close();


        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CertificateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

我發布此答案是為了提供將.pkcs12文件轉換為keystore.bks的 cmdline-version

需要什么:

如果您不知道如何生成.PKCS12文件,請查看以下站點:

對於此示例,我使用jetty.pkcs12作為源。 命令生成:keystore.bks /usr/local/share/java/portecle-1.9/ 是我安裝下載的 Portecle-Tool (.ZIP) 的路徑

keytool -importkeystore -srckeystore jetty.pkcs12 \
-srcstoretype PKCS12 -deststoretype BKS -providerpath \
/usr/local/share/java/portecle-1.9/bcprov.jar -provider \
org.bouncycastle.jce.provider.BouncyCastleProvider-destkeystore \
keystore.bks

現在可以在Android下使用BKS-Keystore了

感謝上一篇帖子,我找到了解決方案並提供了這個 cmd。 希望它可以幫助某人!

采用:

KeyStore.getInstance("BKS");

要么

KeyStore.getInstance("PKCS12");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM