res/raw内のキーストア読み込めない

1,085 views
Skip to first unread message

yos-mas

unread,
Apr 11, 2012, 3:04:38 AM4/11/12
to android-g...@googlegroups.com
yos-masと申します。

下記ページを参考に、res/raw内のキーストアを読み込んで
https通信を行おうとしています。
しかし、いくら試しても

 keyStore.load(in, passwdchars);

のところで、

 java.io.IOException: Wrong version of key store.

の例外が発生します。

bcprov-jdk15on-147.jarをインストールし、
キーストア生成時に-storetype BKSの指定もしたのですが
解決できませんでした。

どなたかご教授お願い致します。

yos-mas

unread,
Apr 11, 2012, 3:58:48 AM4/11/12
to android-g...@googlegroups.com
連投すみません。追記です。

エミュレータの/system/etc/security/cacerts.bksを取得して
res/raw内に置いて試したところ、
Wrong version of key storeのエラーが出なくなりました。
ということは、キーストア自体に問題があるということなのでしょうか。

依然、解決策は見つかっておりませんので、ご教授お願い致します。

2012年4月11日水曜日 16時04分38秒 UTC+9 yos-mas:

nandai

unread,
Apr 11, 2012, 1:00:48 PM4/11/12
to android-g...@googlegroups.com
yos-masさんこんばんわ。
nandaiです。

下記はAndroid 4.0.4のソースの抜粋ですが、どうやら証明書のバージョンチェックに
引っかかっているようですね。

この辺のことはほとんど何も知らないのでこれ以上の情報はありませんが参考までに。

class KeyStore {
    KeyStoreSpi implSpi;

    void load(InputStream stream, char[] password) {
        implSpi.engineLoad(stream, password);
    }
}

abstract class KeyStoreSpi {
    abstract void engineLoad(InputStream stream, char[] password);
}

class JDKKeyStore extends KeyStoreSpi implements BCKeyStore {
    private static final int STORE_VERSION = 1;

    void engineLoad(InputStream stream, char[] password) {
        DataInputStream dIn = new DataInputStream(stream);
        int version = dIn.readInt();
       
        if (version != STORE_VERSION) {
            if (version != 0) {
                throw new IOException("Wrong version of key store.");
            }
        }
    }
}

class BouncyCastleProvider extends Provider implements ConfigurableProvider {
    void setup() {
        put("KeyStore.BKS", "org.bouncycastle.jce.provider.JDKKeyStore");
    }
}

参考情報
http://java.sun.com/j2se/1.3/ja/docs/ja/tooldocs/win32/keytool.html#DName

/*--------------------------------

  http://www.log-tools.net/
  http://d.hatena.ne.jp/nandai2/

--------------------------------*/

2012年4月11日水曜日 16時58分48秒 UTC+9 yos-mas:

yos-mas

unread,
Apr 11, 2012, 11:00:42 PM4/11/12
to android-g...@googlegroups.com
nandaiさん

返信ありがとうございました。

私も証明書周りのことに詳しくないので、
とりあえず証明書について調べてみました。 
どうやらX509という証明書を使っていて、
v1, v2, v3のバージョンがあるということは分かりました。

バージョンチェックに引っかかるというのは、
X509 v1でなければいけないということなのでしょうか。

宜しくお願い致します。

2012年4月12日木曜日 2時00分48秒 UTC+9 nandai:

nandai

unread,
Apr 12, 2012, 10:09:25 AM4/12/12
to android-g...@googlegroups.com
nandaiです。

> バージョンチェックに引っかかるというのは、
> X509 v1でなければいけないということなのでしょうか。

ソースを見る限りそうなんだろうと思います。

あとは、keytoolに次のオプションを追加してみてはどうでしょう。
    -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider

(下記URLでは-providerとなっていますが自分の環境ではこのオプションはありませんでした)

http://stackoverflow.com/questions/6933103/wrong-version-keystore-when-doing-https-call

これでうまくいくかどうかは分かりませんが試してみて下さい。


/*--------------------------------

  http://www.log-tools.net/
  http://d.hatena.ne.jp/nandai2/

--------------------------------*/


2012年4月12日木曜日 12時00分42秒 UTC+9 yos-mas:

yos-mas

unread,
Apr 13, 2012, 12:04:33 AM4/13/12
to android-g...@googlegroups.com
返信ありがとうございます。

その後色々試しまして、
結果としては、https通信に成功しました。

今まで最新版のbcprov-jdk15on-147.jarを使っていたのですが、
bcprov-jdk16-146.jarに変えたら、
参考ページのやり方であっさり成功しました。
(公式ページには最新版しかなさそうなので、ネット上を探しましたが)

ただ、keytool -listで証明書を確認したところ、
バージョン3と出ました。
(最新版を使っても同じでした。)
なんでバージョンチェックに引っかからなくなるのか良く分からず、
少しモヤモヤは残ったままです...。

とりあえず通信には成功したので、ご報告まで。
ありがとうございました。

2012年4月12日木曜日 23時09分25秒 UTC+9 nandai:

nandai

unread,
Apr 13, 2012, 12:51:05 PM4/13/12
to android-g...@googlegroups.com
nandaiです。
通信成功おめでとうございます。

気になったので私も試してみたところ、bcprov-jdk15on-147.jarではver.3、
bcprov-jdk16-146.jarではver.2のファイルが生成されていました。

実際にそれぞれで生成したファイルの先頭4バイトがbcprov-147では0x00000002(ver.3)、
bcprov-146では0x00000001(ver.2)となっているのを確認済みです。

ちなみにAndroidで使用されているJDKKeyStoreは最新のAndroid 4.0.4でも
bcprov-146相当のソース(前に返信した内容)のため、ver.3のファイルだと例外が発生
することになりますが、bcprov-147では該当箇所が以下の通り変更されています。


class JDKKeyStore extends KeyStoreSpi implements BCKeyStore {
    private static final int    STORE_VERSION = 2;


    void engineLoad(InputStream stream, char[] password) {
        DataInputStream dIn = new DataInputStream(stream);
        int version = dIn.readInt();
       
        if (version != STORE_VERSION) {
            if (version != 0 && version != 1) {

                throw new IOException("Wrong version of key store.");
            }
        }
    }
}

でもkeytool -list -vで証明書を確認するとどちらもバージョン:3と表示されますね。
何のバージョンかなあ。署名アルゴリズム?ま、Androidの話題からは外れそうですし
私も色々分かったのでこの辺にしておきます。


/*--------------------------------

  http://www.log-tools.net/
  http://d.hatena.ne.jp/nandai2/

--------------------------------*/


2012年4月13日金曜日 13時04分33秒 UTC+9 yos-mas:
Reply all
Reply to author
Forward
0 new messages