web-dev-qa-db-ja.com

PKCS#12:DerInputStream.getLength()例外

Keytoolコマンドを使用して証明書を生成します。

keytool -genkeypair -alias myRSAKey -keyalg RSA -keysize 1024 -keystore test.p12 -storepass test -storetype pkcs12

次に、ファイルをバイトとして取得した後、JavaセキュリティAPIを使用してそれをロードしようとした場合]:

KeyStore ks = KeyStore.getInstance("PKCS12");
try{
   ks.load(new ByteArrayInputStream(data), "test".toCharArray())
} catch (Exception e){
   ...
}

DerInputStream.getLength()を取得します:lengthTag = 127、大きすぎる例外。

なにが問題ですか?

19
karlipoppins

私はこの問題を抱えていて、グーグルの深さを検索しましたが、それでも答えを見つけることができませんでした。数日間、ひどい品質のレガシーコードと戦った後、私はこのエラーの原因を見つけました。

KeyStore.load(InputStream is, String pass);

このメソッドはInputStreamを受け取り、そのようなInputStreamに問題がある場合、この例外がスローされます。

  • InputStreamが間違った/空白/作成されたばかりのファイルを指している
  • InputStreamはすでに開いているか、他の何かがリソースを保持しています
  • InputStream すでに使用され、読み取られていました、つまり、InputStreamの次のバイトの位置は、その終わりです

最後の1つは私の問題の原因でした。コードは証明書からInputStreamを作成し、それを2つのKeyStore.load()呼び出しで使用し始めました。最初の呼び出しは成功し、2番目の呼び出しは常にこのエラーを受け取りました。

18
ibrabeicker

おそらく、作成した証明書の末尾に余分な文字があり、別の証明書であると誤って解釈されます。最後に1行以上の空白行を使用します。

参照: Java Certificate Parsing

8
Amanpreet

同様の問題を持つ他の人のために:

"keystore load: DerInputStream.getLength(): lengthTag=109, too big."

私にとっての解決策は、パラメータを削除することでした:-storetype pkcs12標準タイプはjksであるため

8
Jan vO

たとえば、コードで証明書のタイプを指定します。

System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); 
2

これは、Android StudioでAndroidXを移行して新しいテストフレームワークを使用した後で発生しました。既存の~/.Android/debug.keystoreを削除することもできませんでした

ソリューションは手動で再生成しました(すべての質問を空として受け入れ、最後の質問で「はい」と答えてください)

$ keytool -genkey -v -keystore debug.keystore -storepass Android -alias androiddebugkey -keypass Android -keyalg RSA -keysize 2048 -validity 10000

そしてコピーします

$ rm ~/.Android/debug.keystore
$ cp debug.keystore ~/.Android/debug.keystore
1
Rohit Mandiwal

これは、Windows 10マシンでローカルに.p12ファイルをコピーして貼り付けたために起こりました。どのように/なぜこれが問題であるかわかりませんが、.p12ファイルを含むプロジェクトを複製し、自分のコードをそれらにポイントすると、ファイルは機能します。ただし、Windowsファイルエクスプローラーのファイルをハードドライブの別の場所にコピーして貼り付けると、このエラーが発生します!!!!

1
Adam Hughes

私の問題(lengthTag=109, too big).p12ファイルは実際にはJKS形式であり、PKCS#12形式ではありませんでした。誰かがファイル拡張子の名前を変更しました。適切なPKCS形式で再生成することにより、問題は解決しました。

Java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
    at Sun.security.util.DerInputStream.getLength(DerInputStream.Java:599)
    at Sun.security.util.DerValue.init(DerValue.Java:365)
    at Sun.security.util.DerValue.<init>(DerValue.Java:320)
    at Sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.Java:1914)
    at Java.security.KeyStore.load(KeyStore.Java:1445)

セキュリティファイルの形式を確認するには、 KeyStore Explorer を使用してファイルを開きます。左下のバーは実際のフォーマットを示しています。

1
Lee Chee Kiam

あなたは何か間違ったことをしています。
私はあなたのコマンドを試し、それからp12をうまくロードしました。
次のコードは機能します:

 FileInputStream fin = new FileInputStream("..\\test.p12");
 KeyStore ks = KeyStore.getInstance("PKCS12");
 ks.load(fin, "123456".toCharArray());
 System.out.println(ks.getCertificate("myrsakey"));

コマンドをそのまま入力すると、keytoolからパスワードが6文字以上である必要があるというエラーが表示されるのではないかと思いました。
そのエラーが発生しませんでしたか? Javaのどのバージョンを使用していますか?
注:証明書を作成する必要がある場合は、このツールを調べることもできます。
http://sourceforge.net/projects/certhelper/

0
Cratylus

Inputstream変数のスコープは、それを宣言しているメソッドにのみであって、static/class変数としてではないことを確認してください。これにより、この例外を回避できます。理由:入力ストリームは、クラス変数として宣言されているため、証明書またはデータを最初にロードした後、閉じられません。メソッドでのみ使用できるようにしてください。

0

同じ問題がありました。

私の解決策は、明らかに間違ったタイプを使用していたため、以下の行でPKCS12をjceksに置き換えることです。

KeyStore clientStore = KeyStore.getInstance("PKCS12");
0
sindacco