CA証明書とandroidの危うい関係 2
Nexus oneでエラーでNexus sでエラーが発生しない違いはどこにあるのだろう、ということでandroid端末にインストールされているCA証明書を覗いてみよう。
androidのCA証明書はBouncy Castle※形式のキーストア(cacerts.bks)として格納されているが、そのパスはシステムプロパティで取得することが出来、通常/system/etc/security/cacerts.bksに決められている。
System.getProperty("javax.net.ssl.trustStore");
cacaert.bksはadbコマンドで抽出することができる。
adb pull /system/etc/security/cacerts.bks e:\cacerts.bks
あとはandroidではなくJava SDKのKeytoolを使ってダンプすればば良い。
keytool -list -v -keystore e:\cacerts.bks -storetype BKS
しかし、ここで注意すべきなのはandroidではインストールされているBouncy CastleがJavaにはインストールされているとは限らないことだ。 未インストールの場合、storetypeにBKSを指定することができないので別途インストールする必要がある。(といってもBouncy Castleのjarを$JAVA_HOME$/jre/lib/extに配置してjava.securityを書き換えるだけだが)
: : # # List of providers and their preference orders (see above): # security.provider.1=sun.security.provider.Sun security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider security.provider.3=sun.security.rsa.SunRsaSign security.provider.4=com.sun.net.ssl.internal.ssl.Provider security.provider.5=com.sun.crypto.provider.SunJCE : :
これでcacerts.bksの中身が見れる。
- Nexus one(冒頭)
キーストアのタイプ: BKS キーストアのプロバイダ: BC キーストアには 56 エントリが含まれます。 :
- Nexus s(冒頭)
キーストアのタイプ: BKS キーストアのプロバイダ: BC キーストアには 104 エントリが含まれます。 :
冒頭だけでエントリ数の差が倍近くあることが判る。
対象になっているサーバの証明書(Entrust社のもの)はNexus Sに登録されており、Nexus oneにはインストールされていなかった。
さて、新たに発行された証明書をインストールする手段だがandroidはPCとは違いルートCA証明書をインストールするのは簡単では無い(/system下のファイル操作になるので、普通はルート権限が必要)。 ベストなのはAndroid MarketのWeb版のようにユーザが何のアクションも起こさずとも自動的に更新されていることだが、この方法はOTAも含めて公開されていないため、実現は困難だ。
では端末にインストールされていない証明書をandroidアプリケーションで利用することは不可能なのだろうか? 否。
※androidのjavaはsunの実装ではなくApache Harmonyを使用しているが、HarmonyのJCE(Java Cryptography Extension)、JSSE(Java Secure Socket Extension)にはBouncy Castleの実装を使用している。
Bouncy Castle