天天看點

建立 Android 上使用的自簽名證書(Creating self-signed certificates for use on Android)

<a target="_blank" href="http://blog.csdn.net/opengl_es">轉載請保留此句:太陽火神的美麗人生 -  本部落格專注于 靈活開發及移動和物聯裝置研究:iOS、Android、Html5、Arduino、pcDuino,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。</a>

<a target="_blank" href="http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/">SSL Certificates Howto</a>

<a target="_blank" href="http://www.openssl.org/docs/HOWTO/keys.txt">OpenSSL Keys Howto</a>

<a target="_blank" href="http://www.openssl.org/docs/HOWTO/certificates.txt">OpenSSL Certificates Howto</a>

<a target="_blank" href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html">Java Keytool</a>

有人可能會問,為什麼我不使用 keytool 生成密鑰和證書,這樣就馬上能有的用了。噢,我有非常強烈的求知欲望,我想學到更多有關 openssl 以及如何處理各種格式密鑰和證的知識。

One might argue why I don’t use keytool to generate the keys and certificates and use them right away. Well, I was very curious about learning more about openssl and how to deal with various formats of keys and certificates.

來,咱們從頭開始。首先,我們需要私鑰。我們使用 openssl 建立:

Let’s start from scratch. First of all we need private keys. We use openssl to create these:

這兩行指令會建立兩個密鑰:<code>client.pem</code> 和 <code>server.pem</code>。我們在下一步中會用它們來簽名我們的證書。通常情況下,我們會建立一個 CA 簽名請求,再把它發送給 CA,CA就會給你頒發證書了。但是,由于我想要自簽名我們的證書,簽名請求這一步就顯得多餘了。

This will create the two keys; <code>client.pem</code> and <code>server.pem</code>. We will use these in the next step to sign our certificates with. In normal cases we would create a CA-signing request, that is sent to a CA who will issue your certificates. But since we want to self-sign our certificates this step is redundant.

另外,如果不想被提示輸入證書的主題行,你也可以給 openssl req 指令傳遞一個 -subj 參數。剛執行的兩條指令主要是建立一個 CA 簽名請求并使用我們的私鑰來簽名輸出的 x509 證書。該證書就會以 pem 格式進行編碼,并且有效期為 365 天。

Additionally, instead of being prompted for the certificate’s subject line you can use the <code>-subj</code> parameter and pass it to the <code>openssl req</code> command. What we just did was basically creating a CA signing request using our private keys to sign the outgoing x509-certificates. The certificates will be coded in pem-format and valid for 365 days.

為了能在 Java 應用中使用我們的密鑰和證書,我們需要将它們導入到密鑰庫裡。首先,我們想讓用戶端信任伺服器證書。要做到這一點,我們必須建立一個用戶端可信庫,并導入伺服器的證書。

In order to use our keys and certificates in Java applications we need to import them into keystores. First of all, we want the client to trust the server certificate. To do this we must create a client trust store and import the server’s certificate.

注意(Note): 在用戶端,我們目前的情況是一個 Android 應用,我們使用 Bouncy Castle 作為我們的提供者,因為它能被 Android 平台支援。  On the client side, which in our case will be an Android app we use Bouncy Castle as our provider since it is supported on the Android platform.

(以下指令用于)建立一個伺服器可信庫,并将用戶端的證書導入。

Create a trust store for the server and import the client’s certificate into it.

目前,我們已經有了兩個可信庫,一個是伺服器的,其中導入了用戶端的證書,一個是用戶端的,其中導入了伺服器的證書。

Currently, we have two trust stores one for the server in which we imported the client’s certificate and one for the client in which we imported the server’s certificate.

Java 的 keytool 工具有一個問題,它無法做到讓我們把一個已存在的私鑰導入到密鑰庫這樣簡單的事情。這個問題的一個變通方案是,把私鑰和證書合并到一個 pkcs12 檔案中(這個檔案格式能被 Java 的 keytool 識别),然後再把這個 pkcs12 密鑰庫導入(譯者注:譯作‘轉換成’可能更好,這表示裡面是密鑰和證書而非這個 pkcs12 密鑰庫,是指派關系而非嵌套關系)到正常的密鑰庫。

A problem with Java’s keytool application is that it won’t let us do such a simple thing as importing an existing private key into a keystore. The workaround to this problem is to combine the private key with the certificate into a pkcs12-file (which is understood by Java’s keytool) and then import this pkcs12 keystore into a regular keystore.

分别組合伺服器和用戶端的證書和私鑰:

Combine the certificate and the private key for the server and client respectively:

Import the created keystores to new ones with common formats:

We should now have all files we need for a successful TLS/SSL mutual authentication. The files we move to our Android project will be: <code>clienttruststore.bks</code> and <code>client.bks</code>. The files we move to our server will be: <code>servertruststore.jks</code> and <code>server.jks</code>.