將下列文字存成 Makefile, 複製到 Android 專案目錄內, 接著在終端機下指令 Make, 就會產生一個鑰匙庫(keystore.p12)放在 app/src/main/res/raw 目錄內, 而私鑰則放在 key 目錄下:
#Makefile
storepass=PKCS12_keystore_for_android_app
tempDir=/dev/shm
saveDir=app/src/main/res/raw
privateDir=key
gen: keystore.p12
keystore.p12: selfsign
openssl pkcs12 -export -inkey $(privateDir)/prvkey.pem -passout pass:$(storepass) -in $(tempDir)/$< -out $(saveDir)/$@
selfsign: buildDirectory
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout $(privateDir)/prvkey.pem -subj "/C=TW/ST=Taiwan/L=TaipeiCity/CN=localhost" -out $(tempDir)/$@
buildDirectory:
[ -d $(saveDir) ] || mkdir $(saveDir)
[ -d $(privateDir) ] || mkdir $(privateDir)
clean:
rm -rf $(tempDir)/selfsign
Android app 可以利用 resources 將它載入, 之後就能讓 SSL Server Socket 正常運作:
// ...
val tls = SSLContext.getInstance("TLS").apply {
val keyStore = KeyStore.getInstance("PKCS12")
val storepass = "PKCS12_keystore_for_android_app"//pass phrase define in Makefile
resources.openRawResource(R.raw.keystore).apply {
keyStore.load(this, storepass.toCharArray())
close()
}
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()).apply {
init(keyStore, storepass.toCharArray())
}
init(kmf.keyManagers, null, null)
}
val sslServer = tls.serverSocketFactory.createServerSocket(8443) .apply{
setReuseAddress(true)
}
如果寫的是 ssl client 端程式, 則要將信任網站的簽署檔(cert file) 放入 keystore, 交由 TrustManager 來管理, Android 可以使用 BKS 格式檔:
val tls = SSLContext.getInstance("TLS").apply {
val keyStore = KeyStore.getInstance("PKCS12")
val storepass = "PKCS12_keystore_for_android_app"//pass phrase define in Makefile
resources.openRawResource(R.raw.keystore).apply {
keyStore.load(this, storepass.toCharArray())
close()
}
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()).apply {
init(keyStore, storepass.toCharArray())
}
val trustStore = KeyStore.getInstance("BKS")
val storepass = "PKCS12_keystore_for_android_app"//pass phrase define in Makefile
resources.openRawResource(R.raw.truststore).apply {
trustStore.load(this, storepass.toCharArray())
close()
}
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
init(trustStore)
}
init(kmf.keyManagers, tmf.trustManagers, SecureRandom())
}
沒有留言:
張貼留言