148

一部のIRCサーバーとSSL接続を行うと(他のサーバーではなく、おそらくサーバーの優先暗号化方式が原因で)、次の例外が発生します。

Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:106)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:556)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:183)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    ... 3 more

最終的な原因:

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:100)
    ... 10 more

この問題を示すサーバーの例は、apture.esper.net:6697(これはIRCサーバーです)です。問題を示さないサーバーの例は、kornbluth.freenode.net:6697です。[当然のことながら、各ネットワーク上のすべてのサーバーは同じ動作を共有します。]

私のコード(前述のように、一部のSSLサーバーに接続するときに機能します)は次のとおりです。

    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, trustAllCerts, new SecureRandom());
    s = (SSLSocket)sslContext.getSocketFactory().createSocket();
    s.connect(new InetSocketAddress(host, port), timeout);
    s.setSoTimeout(0);
    ((SSLSocket)s).startHandshake();

例外をスローするのは、最後のstartHandshakeです。そして、はい、「trustAllCerts」で起こっているいくつかの魔法があります。そのコードはSSLシステムに証明書を検証しないように強制します。(つまり、証明書の問題ではありません。)

明らかに1つの可能性は、esperのサーバーが正しく構成されていないことですが、esperのSSLポートに問題がある人への参照を検索しても見つかりませんでした。また、「openssl」がそれに接続します(以下を参照)。ですから、これがJavaのデフォルトのSSLサポートの制限なのか、それとも何かなのか疑問に思います。助言がありますか?

コマンドラインから「openssl」を使用してapture.esper.net6697に接続すると、次のようになります。

~ $ openssl s_client -connect aperture.esper.net:6697
CONNECTED(00000003)
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify return:1
---
Certificate chain
 0 s:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
   i:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
Server certificate
-----BEGIN CERTIFICATE-----
[There was a certificate here, but I deleted it to save space]
-----END CERTIFICATE-----
subject=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
issuer=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
No client certificate CA names sent
---
SSL handshake has read 2178 bytes and written 468 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 51F1D40A1B044700365D3BD1C61ABC745FB0C347A334E1410946DCB5EFE37AFD
    Session-ID-ctx: 
    Master-Key: DF8194F6A60B073E049C87284856B5561476315145B55E35811028C4D97F77696F676DB019BB6E271E9965F289A99083
    Key-Arg   : None
    Start Time: 1311801833
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

すでに述べたように、その後は正常に接続されます。これは、私のJavaアプリで言うことができる以上のことです。

関連する場合は、OS X 10.6.8、Javaバージョン1.6.0_26を使用しています。

4

21 に答える 21

122

問題はプライムサイズです。Java が受け入れる最大許容サイズは 1024 ビットです。これは既知の問題です ( JDK-6521495を参照)。

私がリンクしたバグ レポートには、BouncyCastle の JCE 実装を使用した回避策が記載されています。うまくいけば、それはあなたのために働くはずです.

アップデート

これはバグJDK-7044060として報告され、最近修正されました。

ただし、制限は 2048 ビットまでしか引き上げられていないことに注意してください。サイズが 2048 ビットを超える場合は、JDK-8072452 - Remove the maximum prime size of DH Keys ;があります。修正は9用のようです。

于 2011-07-27T22:39:41.737 に答える
69

「Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files」の回答はうまくいきませんでしたが、BouncyCastle の JCE プロバイダーの提案はうまくいきました。

Mac OSC 10.7.5 で Java 1.6.0_65-b14-462 を使用して行った手順は次のとおりです。

1) これらの jar をダウンロードします。

2) これらの jar を $JAVA_HOME/lib/ext に移動します。

3) $JAVA_HOME/lib/security/java.security を次のように編集します: security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider

JREを使用してアプリを再起動し、試してみてください

于 2015-03-20T22:12:34.157 に答える
13

上記の答えは正しいですが、回避策の観点から、BouncyCastleの実装を優先プロバイダーとして設定すると、問題が発生しました。

java.lang.ArrayIndexOutOfBoundsException: 64
    at com.sun.crypto.provider.TlsPrfGenerator.expand(DashoA13*..)

これは、私が見つけた1つのフォーラムスレッドでも説明されていますが、解決策については触れられていません。 http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

私は自分のケースに適した代替ソリューションを見つけましたが、まったく満足していません。解決策は、Diffie-Hellmanアルゴリズムがまったく使用できないように設定することです。次に、サーバーが代替アルゴリズムをサポートしていると仮定すると、サーバーは通常のネゴシエーション中に選択します。明らかに、これの欠点は、誰かが1024ビット以下でDiffie-Hellmanのみをサポートするサーバーをなんとかして見つけた場合、これは実際には以前は機能していた場所では機能しないことを意味します。

SSLSocketが与えられた場合(接続する前)に機能するコードは次のとおりです。

List<String> limited = new LinkedList<String>();
for(String suite : ((SSLSocket)s).getEnabledCipherSuites())
{
    if(!suite.contains("_DHE_"))
    {
        limited.add(suite);
    }
}
((SSLSocket)s).setEnabledCipherSuites(limited.toArray(
    new String[limited.size()]));

不快な。

于 2011-07-28T16:30:49.783 に答える
13

jdk で DHE を完全に無効にし、jre/lib/security/java.security を編集して、DHE が無効になっていることを確認します。お気に入り

jdk.tls.disabledAlgorithms=SSLv3, DHE.

于 2015-07-10T07:44:48.493 に答える
12

プロバイダーを動的にインストールできます。

1) これらの jar をダウンロードします。

  • bcprov-jdk15on-152.jar
  • bcprov-ext-jdk15on-152.jar

2)jarをWEB-INF/lib(またはクラスパス)にコピーします

3) プロバイダーを動的に追加します。

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

于 2015-05-07T12:44:48.713 に答える
8

これはかなり古い投稿ですが、Apache HTTPD を使用している場合は、DH サイズを制限できます。http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadhを参照してください。

于 2014-11-19T17:08:12.340 に答える
6

jdk1.7.0_04 を使用している場合は、jdk1.7.0_21 にアップグレードします。そのアップデートで問題が修正されました。

于 2013-05-22T08:29:27.370 に答える
5

Java ダウンロード サイトから「Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files」をダウンロードし、JRE 内のファイルを置き換えてみてください。

これはうまく機能し、BouncyCastle を使用する必要さえありませんでした。標準の Sun JCE はサーバーに接続できました。

PS。ポリシー ファイルを変更する前に BouncyCastle を使用しようとしたときに同じエラー (ArrayIndexOutOfBoundsException: 64) が発生したため、状況は非常に似ているようです。

于 2011-11-17T21:02:40.067 に答える
1

JDK 8 にアップグレードすることで問題を解決しました。

于 2016-06-01T15:08:47.950 に答える
1

私は JDK 1.6.45 で coldfusion 8 を使用していますが、画像の代わりに赤い十字が表示されるだけでなく、cfhttp が ssl でローカル Web サーバーに接続できないという問題がありました。

私のcoldfusion 8で再現するテストスクリプトは

<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">

これにより、「I/O 例外: ピアが認証されていません」という非常に一般的なエラーが発生しました。次に、ルート証明書と中間証明書を含むサーバーの証明書を Java キーストアと Coldfusion キーストアに追加しようとしましたが、何も役に立ちませんでした。次に、問題をデバッグしました

java SSLPoke www.onlineumfragen.com 443

そして得た

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
    ... 10 more

次に、Webサーバー(私の場合はapache)にはssl用の非常に最新の暗号があり、非常に制限的であり(qualysスコアa +)、1024ビットを超える強力なdiffie hellmannキーを使用するという考えがありました. 明らかに、coldfusion と Java jdk 1.6.45 ではこれを管理できません。冒険の旅の次のステップは、Java 用の代替セキュリティ プロバイダのインストールを検討することでした。その結果、弾む城に決めました。http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/も参照してください。

次に、ダウンロードしました

bcprov-ext-jdk15on-156.jar

http://www.bouncycastle.org/latest_releases.htmlから、C:\jdk6_45\jre\lib\ext または jdk がある場所にインストールします。coldfusion 8 の元のインストールでは、C:\JRun4\ の下になります。 jre\lib\ext ですが、coldfusion ディレクトリの外にある新しい jdk (1.6.45) を使用しています。bcprov-ext-jdk15on-156.jar を \ext ディレクトリに配置することが非常に重要です (これには約 2 時間かかりました ;-) 次に、ファイル C:\jdk6_45\jre\lib\security\ を編集しました。 java.security (editor.exe ではなくワードパッドを使用) を作成し、新しいプロバイダーを 1 行に入力します。その後、リストは次のようになりました

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
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
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

(位置 1 の新しいものを参照してください)

次に、coldfusion サービスを完全に再起動します。あなたはその後することができます

java SSLPoke www.onlineumfragen.com 443 (or of course your url!)

そしてその感覚を楽しんでください...そしてもちろん

どんな夜とどんな日。うまくいけば、これが誰かに(部分的または完全に)役立つことを願っています。ご不明な点がございましたら、info ... (上記のドメイン) までメールをお送りください。

于 2017-01-05T16:28:13.443 に答える
0

まったく同じ例外エラーが返されました。インターネットを何時間もサーフィンした後でも簡単に修正できました.

oracle.com で見つけた最新バージョンの jdk をダウンロードしてインストールし、インストールされた新しい jdk のディレクトリを Jboss アプリケーション サーバーに指定しました。

Jbossを再起動し、再処理し、問題を修正しました!!!

于 2016-04-05T16:20:42.373 に答える
0

Bamboo 5.7 + Gradle プロジェクト + Apache でこのエラーが発生しました。Gradle は、SSL 経由でサーバーの 1 つからいくつかの依存関係を取得しようとしました。

解決:

  1. DH パラメータを生成します。

OpenSSL の場合:

openssl dhparam 1024

出力例:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. 出力を証明書ファイルに追加 (Apache の場合 - SSLCertificateFileparam)

  2. Apacheを再起動します

  3. Bamboo を再起動する

  4. プロジェクトを再度ビルドしてみてください

于 2016-12-05T07:59:02.100 に答える
0

IBM JDK を使用して Java SVN クライアントで svn.apache.org にアクセスすると、同様のエラーが発生していました。現在、svn.apache.org はクライアントの暗号設定を使用しています。

パケット キャプチャ / javax.net.debug=ALL を使用して 1 回だけ実行した後、単一の DHE 暗号のみをブラックリストに登録することができ、問題は解決しました (代わりに ECDHE がネゴシエートされます)。

.../java/jre/lib/security/java.security:
    jdk.tls.disabledAlgorithms=SSL_DHE_RSA_WITH_AES_256_CBC_SHA

クライアントを簡単に変更できない場合の素早い修正です。

于 2017-01-07T17:00:45.627 に答える
-1

サーバーが DH を含まない暗号をサポートしている場合は、クライアントに強制的にその暗号を選択させ、DH エラーを回避することができます。そのような:

String pickedCipher[] ={"TLS_RSA_WITH_AES_256_CBC_SHA"};
sslsocket.setEnabledCipherSuites(pickedCipher);

正確な暗号を指定すると、長期的には壊れやすいことに注意してください。

于 2015-07-01T23:33:36.227 に答える
-1

私にとっては、次のコマンドラインで問題が解決しました。

java -jar -Dhttps.protocols=TLSv1.2 -Ddeployment.security.TLSv1.2=true -Djavax.net.debug=ssl:handshake XXXXX.jar

JDK 1.7.0_79 を使用しています

于 2016-10-18T20:17:07.807 に答える