web-dev-qa-db-ja.com

理解Javaセキュリティプロバイダ

私が最近遭遇した以下の問題を使用して、Javaのセキュリティプロバイダー、暗号、および暗号化全般をよりよく理解したいと思っています。

Solaris 10ホストから、SSLハンドシェイク中に InstallCert ツールを使用して、Java 1.6.0_81を実行して2つのADホストの1つに)を実行すると、次のエラーが発生しました。

]$ Java InstallCert Host1.example.com:636 
Loading KeyStore /usr/jdk/instances/jdk1.6.0/jre/lib/security/cacerts...
Opening connection to Host1.example.com:636...
Starting SSL handshake...

javax.net.ssl.SSLException: Java.lang.RuntimeException: Could not parse key values
        at com.Sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.Java:190)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.Java:1747)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.Java:1708)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.Java:1691)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1222)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1199)
        at InstallCert.main(InstallCert.Java:98)
Caused by: Java.lang.RuntimeException: Could not parse key values
        at Sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.Java:954)
        at Sun.security.pkcs11.P11Key$P11ECPublicKey.getW(P11Key.Java:975)
        at com.Sun.net.ssl.internal.ssl.ECDHClientKeyExchange.<init>(ECDHClientKeyExchange.Java:40)
        at com.Sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.Java:782)
        at com.Sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.Java:241)
        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:943)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1188)
        at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1215)
        ... 2 more
Caused by: Java.io.IOException: extra data given to DerValue constructor
        at Sun.security.util.DerValue.init(DerValue.Java:368)
        at Sun.security.util.DerValue.<init>(DerValue.Java:277)
        at Sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.Java:945)
        ... 11 more

2番目のホストはエラーを出しません。ここで収集できた唯一の違いは、Host1.example.comの暗号です。これはAES256-SHAです。 Host2.example.comの暗号はAES128-SHAです。

]$ echo -n | openssl s_client -connect Host1.example.com:636 | grep 'Cipher is'
New, TLSv1/SSLv3, Cipher is AES256-SHA

]$ echo -n | openssl s_client -connect Host2.example.com:636 | grep 'Cipher is'
New, TLSv1/SSLv3, Cipher is AES128-SHA

私の質問は:

  • Javaセキュリティプロバイダーの目的と暗号化におけるそれらの役割は何ですか?
  • このエラーが発生するのは、Host1.example.comでのAES256-SHAの暗号化についてどうですか?
  • 問題を解決するために、最終的にこのセキュリティプロバイダーをJava.securityファイルでコメント化しました。

    security.provider.1=Sun.security.pkcs11.SunPKCS11 ${Java.home}/lib/security/sunpkcs11-solaris.cfg

バグの多いプロバイダー とCipherのこの組み合わせがこの問題の原因であると思われますか?そのリンクは「EC」を参照していますが、それが何かはわかりません。

ポインタと洞察は大歓迎です!

2
KM.

さらに具体的には、ECDHはDiffie-Hellmanの楕円曲線バリアントであり、ここでは鍵交換に使用されます。ほとんど確実にECDHE、ephemeralECDHの形式ですが、ここの情報から確認することはできません。

サーバー上で「the」暗号を言うことはできません。実質的にすべてのSSL/TLS実装は、複数の暗号スイート(省略された、不正確な暗号)をサポートしています。通常、クライアントはクライアントがサポートするスイートの大きなリストを提供し、サーバーはサーバーがサポートするスイートの中から「最良の」スイートを選択します。この場合、「最良の」ものは複雑であり、(多くの)他の質問があります。 。 AD ass-u-me ADがWindows Active Directoryを意味する場合でも、サポートするスイートがわからないため、Windowsのバージョン、およびおそらくADのバージョンに依存すると考えています。

Host1に対するJava6の試みは、サーバーが選択したECDHを使用して少なくとも1つのスイートを提供したが、Sun PKCS11プロバイダーでは機能しませんでした。 Solarisについては確信がありませんが、SunのWindowsおよびLinux Java6ディストリビューションには組み込みのECCプロバイダーが含まれていなかったため、PKCS11が(申し立てにより)サポートしているものへのアクセスを提供しない限り、ECDHスイートを提供(または同意)しません。 Java7と8doにはECCが組み込まれていますが、プロバイダーポジション1にPKCS11がある場合でも優先されます。

あなたのopenssl s_clientがHost1でプレーンなRSAスイートをネゴシエートしました。 (OpenSSL名AES256-SHAは、実際にはTLS_RSA_WITH_AES_256_CBC_SHAを意味します。歴史的な理由により、OpenSSL名はプレーンRSA鍵交換のRSAを省略します。)OpenSSLバージョン0.9。*はデフォルトでECCをサポートせず、この結果を生成します。 (技術的には、十分に上手く行けば0.9.8でECCを実行できますが、そうだと思います。)OpenSSL(アップストリーム)1.0.0以降は、すべての標準ECDHスイートをサポートします。そして、それらを好みます、サーバーに1つを選択させると私は期待します。 OpenSSLのRedHatパッケージは、最近の特許の問題までECCが省略されていることは知っています。明らかにRedHatはSolarisには適用されませんが、おそらく(a?)Solarisパッケージャーが同じことをしたのかもしれません。誰かがビルドを微調整してECCをサポートしたがそれを好まなかった可能性もあり、サーバーはその設定に従いました。 -cipher ECDH:!aNULLを追加して、ECDHスイートの取得に成功するかどうかを確認し、成功するかどうかを確認します。

Javaで乱暴に信頼する:いずれの場合も、opensslではInstallCertは必要ありません。行う

echo Q | openssl s_client -connect $Host:$port -showcerts \
| nawk '/--BEG/,/--END/{print>"anchor"} /--END/{close("anchor")}'

つまり、-showcertsを追加して、証明書データのlastブロックをファイルに選択し、次に

 keytool -keystore $YOURJRE/lib/security/cacerts -importcert -file anchor -alias $NAME

ここで、$NAMEは、文字と数字の短い名前only地方自治体(ドメインなど)のニーモニックであり、パスワードを入力しますchangeitと確認します。

1

Javaセキュリティプロバイダーの目的と暗号化におけるそれらの役割は何ですか?

私のjdk/jre/lib/security/Java.securityファイルからの抜粋:

#
# This is the "master security properties file".
#
# In this file, various security properties are set for use by
# Java.security classes. This is where users can statically register
# Cryptography Package Providers ("providers" for short). The term
# "provider" refers to a package or set of packages that supply a
# concrete implementation of a subset of the cryptography aspects of
# the Java Security API. A provider may, for example, implement one or
# more digital signature algorithms or message digest algorithms.
#
# Each provider must implement a subclass of the Provider class.
# To register a provider in this master security properties file,
# specify the Provider subclass name and priority in the format
#
#    security.provider.<n>=<className>
#
# This declares a provider, and specifies its preference
# order n. The preference order is the order in which providers are
# searched for requested algorithms (when no specific provider is
# requested). The order is 1-based; 1 is the most preferred, followed
# by 2, and so on.
#
# <className> must specify the subclass of the Provider class whose
# constructor sets the values of various properties that are required
# for the Java Security API to look up the algorithms or other
# facilities implemented by the provider.
#
# There must be at least one provider specification in Java.security.
# There is a default provider that comes standard with the JDK. It
# is called the "Sun" provider, and its Provider subclass
# named Sun appears in the Sun.security.provider package. Thus, the
# "Sun" provider is registered via the following:
#
#    security.provider.1=Sun.security.provider.Sun
#
# (The number 1 is used for the default provider.)
#
# Note: Providers can be dynamically registered instead by calls to
# either the addProvider or insertProviderAt method in the Security
# class.

[編集済み]バグの原因に関するdave_thompsonの回答を出して、ここで回答する資格のある1つの質問のみに回答を修正します。

0
avgvstvs