中華パッドを手に入れて以来、くだらないアプリを作ったりして遊んでてるんですが、Android 4.0.3 のJava JCEについて 調べたので書いてみたいと思います。

Java JCEとは

AndroidではアプリをJavaで作るわけですが、暗号やSSLや証明書なんかを使おうとする時には、 JCE(Java Cryptography Extension) という拡張を使えます。これは、暗号アルゴリズムの実装を自分やサードパーティの人が作ったものを組み込んで 同じインタフェースで使えるといったもので、Androidでもこれが使えます。
blog-fig-androidjce-20121010-f1

AndroidのJCE

「AndroidではBouncyCastleのサブセットが入ってるんだぜ!」とか 「Android 4.0からOpenSSL使ってるんだぜ!」とか、みんなしたり顔で言ったりしてます。 BouncyCastleは最も使われていると思うオープンソースのJCE対応のJava暗号ライブラリで 私も常日頃、大変お世話になっていますが、「サブセットっていうけど何が違うんだー」、 「OpenSSLとBouncyの棲み分けはどうなっとるんじゃー」という疑問について 詳しく説明してくれるページなどもなく悶々とした日々を送ってきたわけです。 JCE好きな私としては「これは自分で調べるしかないな」と思った次第です。

AndroidのCryptographic Provider

JCEではプロバイダという単位で暗号アルゴリズムのセットを提供しています。BouncyCastleもその一つです。 例えば Windows 版のOracle Java 1.6.0_20とかでは以下のような9つのプロバイダが標準で提供されています。

JCEプロバイダ名Ver.内容
SUN1.6証明書の検証、証明書ストア、証明書、DSA署名、ハッシュ、キーストア
SunRsaSign1.5RSA署名、RSA鍵
SunJSSE1.6SSL
SunJCE1.6RSA,DES,3DES,AES,BlowFish,ARCFOUR,RC2,PBE,DH,HMAC等
SunJGSS1.0GSS Api
SunSASL1.5SASL認証API
XMLDSig1.0XML署名
SunPCSC1.6スマートカード
SunMSCAPI1.6RSA,証明書ストア,RSA署名,セキュア乱数

(あれれ?楕円関係どこいった???)

早速、Android 4.0.3 のJCEプロバイダを見てみるとこんな感じ。

JCEプロバイダ名Ver.内容
AndroidOpenSSL1.0SSL,SHA系ハッシュ
DRLCertFactory1.0X509 CertificateFactoryのみ
BC
(BouncyCastle)
1.46 諸々の暗号アルゴリズム。実はオリジナルのBouncyCastleをいじっていて あまり使われないアルゴリズムを省き、OpenSSLの暗号アルゴリズムも使えるようにしている。
Crypto1.0Apache HarmonyのSHA1、DSAの実装のみ
HarmonyJSSE1.0Apache HarmonyのSSL、トラストアンカ、証明書対応

blog-fig-androidjce-20121010-f2
ざっくりと以下のことが言えるのかと思います。
  • Androidでは、Oracle Javaと同じく基本的な暗号、証明書の検証、証明書ストア、SSLの機能は備えている。
  • Androidは、Oracle Javaと違いXML署名、スマートカード用のプロバイダは無い。
  • AndroidのJCEによりSSLやルート証明書ストアや(ほんの)一部の暗号が透過的に利用できるようになっている。
OpenSSLの豊富な暗号アルゴリズムを活用できたり、OpenSSLのある意味厳格な証明書検証の機能を使えるのかと思ってましたが、そんな事はなくてルート証明書ストア、SSL、AES暗号のために部分的に利用できるようになっているに過ぎないってことなんですね。

AndroidのJCEからのOpenSSLの利用

OpenSSLで実装されたアルゴリズムをJCEから利用するためには2つの方法がありそうです。

  • AndroidOpenSSLプロバイダを用いてSSLやSHA系の実装を利用する。
  • Android用に変更されたBouncyCastleプロバイダからAES暗号を利用する。
BouncyCastleプロバイダから指定できるOpenSSL実装のアルゴリズムにはたった3つの 128ビット、192ビット、256ビットのAES暗号しかなくてアルゴリズム名は以下のようになっています。
  • PBEWITHMD5AND128BITAES-CBC-OPENSSL
  • PBEWITHMD5AND192BITAES-CBC-OPENSSL
  • PBEWITHMD5AND256BITAES-CBC-OPENSSL
末尾に"-OPENSSL"がついているのが特徴かと思います。

前回のブログでは、Androidの標準のルート証明書ストアはAndroidCAStoreとして利用することができ、 OpenSSLのルート証明書ストアを拡張したような証明書ストアになっていますが、 AndroidOpenSSLプロバイダではなくHarmonyJSSEプロバイダに入っています。 SSLに関してはAndroidOpenSSLとHarmonyJSSEの2つのプロバイダがありますが、 AndroidOpenSSLプロバイダのものを優先して使うようになっているようです。

Androidのスリム化しOpenSSL拡張されたBouncyCastle JCEプロバイダ

AndroidにバンドルされているBouncyCastleプロバイダは、 機能が制限されているという話を聞くんですが、アルゴリズムの一覧を眺めて Androidにバンドルされているものと、オリジナルのとでどのように違うのか まとめてみました。 Android 4.0.3にバンドルされているものは、 最新の1つ前のバージョンのBouncyCastle 1.46(2011年2月23日リリース)をベースにしているのでこれと比較してみたいと思います。

アルゴリズムタイプ、内容Android 4.0.3 BouncyCastleオリジナルBouncy Castle 1.46
プロパティ全数378個911個
暗号プリミティブ
Cipher数28個102個
Cipherの違い AES,ARC4,BLOWFISH,DES,3DES,AES,RC2,RC4,RSAがある。 アルゴリズム名*-OPENSSLによりOpenSSL実装のAES暗号が使える。 左に加えCamellia,SEED,GOST,CAST5,CAST5,ECIES,ELGAMAL,Grain,HC,IES, Noekeon,RC2,RC5,RC6,RSA,RSAOAEP,SALSA,SEED,Skipjack,Serpent,TEA,Twofish,VMPC,XTEA, などがある。 OpenSSL実装は使えない。
MessageDigest数7個15個
MessageDigestの違い MD5,SHA1,SHA256,SHA384,SHA512がある。 左に加えGOST,MD2,MD4,RIPEMD,SHA224,Tiger,WHIRLPOOLがある。
Signature数12個46個
Signatureの違い {MD5,SHA1,SHA256,SHA384,SHA512}with{RSA,DSA,ECDSA}がある。 左に加えて公開鍵系ではRSAPSS、ECDSA-CVC、ECNR、ECGOST、GOST、 ハッシュアルゴリズムとしてはMD2、MD4、MD5、RIPEMDがある。
Mac数7個35個
Macの違い {MD5,SHA1,SHA256,SHA384,SHA512}HMAC,PBEWITHHMACSHA1がある。 左に加えて{DES,AES}CMAC、{DES,GOST,RC2,RC5,Skipjack,VMPC}MAC、 {MD2,MD4,MD5,RIPEMD}HMACがある。
KeyAgreement数2個6個
KeyAgreementの違い DH,ECDH 左に加えてECDHC,ECMQVがある。
PKI関連
CertPathBuilder数1個3個
CertPathBuilder違い 通常のPKIX,RFC3280のパス構築 左に加えて属性証明書のパス構築ができる
CertPathValidator数1個3個
CertPathValidator違い 通常のPKIX,RFC3280のパス検証 左に加えて属性証明書のパス検証ができる
CertStore数1個3個
CertStoreの違い Collectionのみ 左に加えてLDAP,Multiがある
CertificateFactory数1個1個
CertificateFactoryの違い X.509のみ 左に同じ
KeyStore数3個9個
KeyStoreの違い BKS,BouncyCastle,PKCS12 左に加え BCPKCS12,PKCS12-{3DES,DEF,DEF-3DES-3DES,DEF-3DES-40RC2}
X509Store数なし8個
X509Storeの違い なし {CERTIFICATE,CRL}{COLLECTION,LDAP}、証明書ペア、属性証明書
X509StreamParser数なし4個
X509StreamParserの違い なし X.509証明書、証明書ペア、CRL、属性証明書
鍵、パラメータ等
AlgorithmParameters数8個34個
AlgorithmParametersの違い AES,BLOWFISH,DES,DH,DSA,RSAOAEP,PKCS12PBE 左に加え Camellia,CAST5,ELGAMAL,GOST,IES,NOEKEON,PSS,RC{2,5,6},SEED,SKIPJACK,Serpent,TEA,Twofish,XTEA
AlgorithmParameterGenerator数2個15個
AlgorithmParameterGeneratorの違い AES,BLOWFISH,DES,DH,DSA,RSAOAEP,PKCS12PBE 左に加え Camellia,CAST5,ELGAMAL,GOST,IES,NOEKEON,PSS,RC{2,5,6},SEED,SKIPJACK,Serpent,TEA,Twofish,XTEA
KeyFactory数4個13個
KeyFactoryの違い DH,DSA,EC,RSA 左に加え ECDH,ECDHC,ECDSA,ECGOST,ECMQV,ELGAMAL,GOST,X.509 がある。
KeyGenerator数10個63個
KeyGeneratorの違い AES,ARC4,BLOWFISH,DES,HMAC{MD5,SHA1,SHA256,SHA384,SHA512} 左に加え Camellia,CAST5,CAST6,GOST,Grain,HC,HMAC{MD2,MD4,SHA224,Tiger,RIPEMD}, Noekon,RC2,RC5,RC6,SALSA,SEED,Skipjack,TEA,Twofish,VMPC,XTEAがある。
KeyPairGenerator数10個63個
KeyPairGeneratorの違い DH,DSA,EC,RSA 左に加え ECDH,ECDHC,ECDSA,ECGOST,ECIES,ECMQV,ELGAMAL,GOST がある。
別名
alias数261個502個
あまり使われていないものを除いてメジャーなものを残して、OpenSSLのAES暗号を 使えるようにしたという感じでしょうか。

あと、パッケージ名についてBouncyCastleオリジナルはパッケージの 名前空間が "org.bouncycastle" になっていますが、 Androidにバンドルされているものは "com.android.org.bouncycastle" になっているので注意が必要です。 オンラインのリファレンスマニュアルにも一切の記述は無かったと思います。

AndroidにバンドルされたBouncyCastleで物足りない時には

AndroidにバンドルされたBouncyCastleは古いとか言われていますが、最新は1.47なので バンドルされた1.46は一年前ぐらいのものだし、それほど古いというわけでもないです。 ただ、BouncyCastleのフルスペックの機能が利用したいみたいな時には BouncyCastleを拡張して入れ替えることができないので、 SpongyCastleというのを 使えばよいそうです。随分昔にBouncyCastleベースで作ったプログラムが結構あるので 時間があるとき、Spongyへの移植を試してみたいと思います。

今回、AndroidのJCEプロバイダを調査するのに自作したツールは そのうち公開できると良いと思ってますが、 Google Playにアカウント登録しないといけないし、まだまだ公開まで先は長そうです。

ちょっと記事が長かったですかね。今日はこの辺で。