19

相互 (双方向) 認証を使用するために、Tomcat 7 で実行されている Java Web サービスをセットアップしようとしています。何をしても、セキュア ポートでのサービスへの接続が機能していないようです。

証明書とキーストアなどを作成するために私がしたことは次のとおりです。

//create the key and certificate for the tomcat server.
keytool -genkey -v -alias tomcat -keyalg RSA -validity 3650 -keystore tomcat.keystore

//create the key and certificate for the client machine.
keytool -genkey -v -alias clientkey -keyalg RSA -storetype PKCS12 -keystore client.p12

//export the client key
keytool -export -alias clientkey -keystore client.p12 -storetype PKCS12 -rfc -file client.cer

//import the client key into the server keystore
keytool -import -v -file client.cer -keystore tomcat.keystore

server.xml ファイル内のコネクタは次のとおりです。

<Connector port="8443"
    maxThreads="150"
    scheme="https"
    secure="true"
    sslProtocol="TLS"
    clientAuth="true"
    keystoreFile="tomcat.keystore"
    keystorePass="tomcat"
    truststoreFile="tomcat.keystore"
    truststorePass="tomcat"/>

tomcat-users.xml ファイルは次のようになります。

<tomcat-users>
    <role rolename="tomcat"/>
    <role rolename="admin"/>
    <!-- note that the actual values for CN, OU, O, L, ST are different, but they match the values created in the client certificate -->
    <user username="CN=name, OU=unit, O=org, L=locality, ST=state, C=US" password="null" roles="admin" />
</tomcat-users>

起動時に以下が設定されます。

-Djavax.net.ssl.keyStoreType=jks
-Djavax.net.ssl.keyStore=tomcat.keystore
-Djavax.net.ssl.keyStorePassword=tomcat
-Djavax.net.ssl.trustStore=tomcat.keystore
-Djavax.net.ssl.trustStorePassword=tomcat
-Djavax.net.debug=SSL

最後に、client.p12 ファイルをクライアント マシンにコピーし、Firefox のクライアント証明書にインポートしました。

最初の問題: Firefox から自分のサービス (例 - https://my.server.com:8443/test ) のエンドポイントに到達すると、「安全な接続に失敗しました」という応答が返されます。SSL は、許容される最大長を超えるレコードを受信しました。(エラーコード:ssl_error_rx_record_too_long)

2 番目の問題: このコネクタをポート 8443 で実行したくありません。ポート 7800 (当社の HTTPS の標準) で実行したいと考えています。コネクタのポートを 7800 に変更してエンドポイント (例 - https://my.server.com:7800/test ) にアクセスしようとすると、ページが解決されません。

だから、どこかで明らかに重要な部分が欠けています。誰でも私のエラーを見ることができますか?

更新: @Dave G からのフィードバック後

コマンドの実行:

openssl s_client -connect localhost:8443 -showcerts

次の出力が生成されます。

CONNECTED(00000003)
140642290976584:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:766:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 263 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

-Djavax.net.debug=SSL もスタートアップに追加しました。これにより、catalina.out ファイルの先頭に以下が生成されます。

trustStore is: tomcat.keystore
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
  Subject: CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Issuer:  CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Algorithm: RSA; Serial number: 0x5485b5a5
  Valid from Mon Dec 08 14:28:53 UTC 2014 until Thu Dec 05 14:28:53 UTC 2024

adding as trusted cert:
  Subject: CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Issuer:  CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
  Algorithm: RSA; Serial number: 0x5485b6af
  Valid from Mon Dec 08 14:33:19 UTC 2014 until Sun Mar 08 14:33:19 UTC 2015

trigger seeding of SecureRandom
done seeding SecureRandom

そして、たくさん:

Ignoring unavailable cipher suite: <suite name>
Ignoring unsupported cipher suite: <suite name>
4

5 に答える 5

35

わかりました-さらに掘り下げた後、ようやくこれが機能するようになりました。@Dave G とこのチュートリアル: Tomcat で双方向 SSL 認証を構成する に感謝します。

一般に、相互認証を機能させるための手順は次のとおりです。

  1. tomcat サーバーの証明書を作成します。クライアントはこの証明書を信頼する必要があります。
  2. tomcat サーバーのキーストアを作成し、サーバー証明書をそこにインポートします。
  3. クライアントの証明書を作成します。サーバーはこの証明書を信頼する必要があります。
  4. クライアント証明書をサーバーキーストアにインポートする
  5. 正しいコネクタ XML で tomcat server.xml ファイルを更新します。

上記の手順は、サーバー上で必要です。完了したら、クライアントをセットアップするには、次の手順を実行します。

  1. クライアント証明書をサーバーからクライアントにコピーします。
  2. サーバーとの通信時にクライアント証明書を使用します (このプロセスは、クライアント アプリケーションの性質によって異なります)。

証明書の構成については、サーバー マシンで次を実行しました。

# For the following commands, set the values in parenthesis to be whatever makes sense for your environment.  The parenthesis are not necessary for the command.

# This is an all-in-one command that generates a certificate for the server and places it in a keystore file, while setting both the certifcate password and the keystore password.
# The net result is a file called "tomcat.keystore". 

keytool -genkeypair -alias (serveralias) -keyalg RSA -dname "CN=(server-fqdn),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keystore tomcat.keystore -keypass (password) -storepass (password)

# This is the all-in-one command that generates the certificate for the client and places it in a keystore file, while setting both the certificate password and the keystore password.
# The net result is a file called "client.keystore"

keytool -genkeypair -alias (clientalias) -keyalg RSA -dname "CN=(client),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keypass (password) -keystore client.keystore -storepass (password) 

# This command exports the client certificate.  
# The net result is a file called "client.cer" in your home directory.

keytool -exportcert -rfc -alias (clientalias) -file client.cer -keypass (password) -keystore client.keystore -storepass (password)

# This command imports the client certificate into the "tomcat.keystore" file.

keytool -importcert -alias (clientalias) -file client.cer -keystore tomcat.keystore -storepass (password) -noprompt

証明書が適切に設定されるようになりました。次のステップは、Tomcat server.xml でコネクタを構成することです。次のようなコネクタ要素を追加します。

<Connector port="8443"
    maxThreads="150"
    scheme="https"
    secure="true"
    SSLEnabled="true"
    truststoreFile="/full/path/to/tomcat.keystore"
    truststorePass="(password)"
    keystoreFile="/full/path/to/tomcat.keystore"
    keystorePass="(password)"
    clientAuth="true"
    keyAlias="serverkey"
    sslProtocol="TLS"/>      

上記の XML では、次の点に注意してください。

  1. 「ポート」属性は、何でもかまいません。
  2. 「keystoreFile」および「truststoreFile」属性は絶対パスである必要があります。デフォルトでは、Tomcat は server.xml と同じディレクトリを検索しません。
  3. 「keystorePass」および「truststorePass」属性は、tomcat.keystore ファイルの作成で使用した (パスワード) 値と一致する必要があります。
  4. 「clientAuth」属性を「true」に設定する必要があります。これが相互認証のトリガーとなります。

さらに、server.xml で、AprLifecycleListner が定義されていないことを確認してください。そのリスナーの XML は次のようになります。

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

その要素は削除/コメントアウトする必要があります。AprLifecycleListener は、上記と同じ方法で構成されないため、これらの手順では機能しません。

トムキャットを再起動します。サーバー構成が完了している必要があります。

クライアント証明書を追加するのは簡単なので、Firefox を使用して作業をテストしました。Firefox を開き、コネクタで定義されたポートで tomcat サービスのエンドポイントに接続してみます。

Ex: https://mytomcatdomain.com:8443/test

これを行うと、Tomcat サーバー用の自己署名証明書を作成したため、信頼できない接続について Firefox から標準アラートを受け取るはずです。クライアント (Firefox) がサーバー (Tomcat) を信頼するように、証明書の例外を追加します。

例外を追加すると、「安全な接続に失敗しました」というメッセージが表示されます。エラー コードは「ssl_error_bad_cert_alert」です。これにより、Tomcat サーバーがクライアントからの認証を要求していることが確認されます。信頼できるクライアント証明書を送信するように Firefox をまだ構成していないため、リクエストは失敗します。

Firefox を設定するには、もう少し魔法をかける必要があります。

// Create a file called DumpPrivateKey.java.  The contents should look like so:
public class DumpPrivateKey {
public static void main(String[] args) throws Exception {
  final String keystoreName = args[0];
    final String keystorePassword = args[1];
    final String alias = args[2];
    java.security.KeyStore ks = java.security.KeyStore.getInstance("jks");
    ks.load(new java.io.FileInputStream(keystoreName), keystorePassword.toCharArray());
    System.out.println("-----BEGIN PRIVATE KEY-----");
    System.out.println(new sun.misc.BASE64Encoder().encode(ks.getKey(alias, keystorePassword.toCharArray()).getEncoded()));
    System.out.println("-----END PRIVATE KEY-----");
  }
}

次のコマンドで Java ファイルをコンパイルします。

javac DumpPrivateKey.java

次に、この小さなユーティリティを使用して、上記で作成した client.keystore ファイルからキーを抽出します。client.keystore および client.cer ファイルを DumpPrivateKey クラスと同じディレクトリにコピーします。以下を実行します。

# This extracts the client key from the client keystore

java DumpPrivateKey client.keystore (password) clientkey > clientkey.pkcs8

# This creates a client.p12 file that can be used by Firefox

openssl pkcs12 -export -in client.cer -inkey clientkey.pkcs8 -password pass:(password) -out client.p12

上記のコードで、(password) は client.keystore の作成に使用したパスワードである必要があることに注意してください。

Firefox の設定を開きます。「証明書」タブをクリックします。「証明書の表示」ボタンをクリックします。[証明書] タブをクリックします。

[インポート] ボタンをクリックし、以前に作成した「client.p12」ファイルを参照します。クライアント証明書のパスワードを入力するよう求められます。

「client.p12」が正常にインポートされたと仮定すると、Firefox ページを更新できるようになり、Tomcat サーバー エンドポイントから正常な応答が得られるはずです。

于 2014-12-11T20:29:09.017 に答える
4

@wbj、JKS から PKCS #12 への PrivateKeyEntry のエクスポートは、はるかに簡単に実行できます。

keytool -importkeystore -srckeystore client.keystore -destkeystore client.p12 -deststoretype PKCS12 -srcalias client -deststorepass <password> -destkeypass <password>

乾杯。

于 2016-01-14T15:44:27.777 に答える
3

Openssl 証明書を使用して正しく動作するようになるまでにはしばらく時間がかかり、このページにアクセスする他の人に役立つようにメモを作成しました。

ステップ 1: 独自のルート CA を作成する

~/openssl$ mkdir -m 0700 /home/ubuntu/openssl/CA /home/ubuntu/openssl/CA/certs /home/ubuntu/openssl/CA/crl /home/ubuntu/openssl/CA/newcerts /home/ubuntu/openssl/CA/private
~/openssl$ touch /home/ubuntu/openssl/CA/indext.txt
~/openssl$ echo 1000 >> /home/ubuntu/openssl/CA/serial
~/openssl$ mv karun-tomcat-root-ca.key CA/private/

~/openssl$ sudo vi /etc/openssl.cnf
    # Make changes here
    dir = /home/ubuntu/openssl/CA
    #optionally change policy definitions as well
~/openssl$ openssl genrsa -des3 -out karun-tomcat-root-ca.key 2048

  #In below command make sure to use CN=<hostname of your machine>
~/openssl$ openssl req -new -x509 -days 36520 -key karun-tomcat-root-ca.key -out karun-tomcat-root-ca.crt -config openssl.cnf

~$ sudo cp ~/openssl/CA/certs/karun-tomcat-root-ca.crt /usr/share/ca-certificates/

  # make sure in the UI you enable/select the certificate created above
~$ sudo dpkg-reconfigure ca-certificates
  # Now reboot ubuntu machine just to make sure certificates are loaded successfully and tomcat picks it

ステップ 2: Tomcat サーバーのキー ペアを作成する

~$ openssl genrsa -out tomcat-server.key 2048

   # Use common name = <Give IP address>, department = Tomcat Server CSR
~$ openssl req -new -sha256 -config ~/openssl/openssl.cnf -key tomcat-server.key -out tomcat-server.csr
~$ openssl x509 -req -sha256 -days 36520 -in tomcat-server.csr -signkey tomcat-server.key -CA ~/openssl/CA/certs/karun-tomcat-root-ca.crt -CAkey ~/openssl/CA/private/karun-tomcat-root-ca.key -CAcreateserial -out tomcat-server.crt 
~$ openssl pkcs12 -export -name karun-tomcat-server-cert -in tomcat-server.crt -out tomcat-server.p12 -inkey tomcat-server.key -CAfile ~/openssl/CA/certs/karun-tomcat-root-ca.crt -caname karun-root -chain

~$ keytool -importkeystore -destkeystore tomcat-server.jks -srckeystore tomcat-server.p12 -srcstoretype pkcs12 -alias karun-tomcat-server-cert

~$ keytool -import -alias karun-root -keystore tomcat-server.jks -trustcacerts -file ~/openssl/CA/certs/karun-tomcat-root-ca.crt

# **(LATER)** Run this once client cert is generated
~$ keytool -importkeystore -alias karun-tomcat-client-cert -srckeystore ~/client-certs/tomcat-client.p12 -srcstoretype PKCS12 -destkeystore tomcat-server.jks -deststoretype JKS

# **(LATER)** Run this once tomcat server started successfully
~$ openssl s_client -connect localhost:8443 -cert ~/client-certs/tomcat-client.crt -key ~/client-certs/tomcat-client.key -debug -showcerts 

ステップ 3: クライアント側の鍵ペアを作成する

~$ openssl genrsa -out tomcat-client.key 2048
  # Use common name = <tomcat-user.xml's user say 'admin'>, department = Tomcat Client CSR
~$ openssl req -new -sha256 -config ~/openssl/openssl.cnf -key tomcat-client.key -out tomcat-client.csr
~$ openssl x509 -req -sha256 -days 36520 -in tomcat-client.csr -signkey tomcat-client.key -CA ~/openssl/CA/certs/karun-tomcat-root-ca.crt -CAkey ~/openssl/CA/private/karun-tomcat-root-ca.key -CAcreateserial -out tomcat-client.crt 
~$ openssl pkcs12 -export -name karun-tomcat-client-cert -in tomcat-client.crt -out tomcat-client.p12 -inkey tomcat-client.key -CAfile ~/openssl/CA/certs/karun-tomcat-root-ca.crt -caname karun-root -chain
~$ (optional step) keytool -importkeystore -destkeystore tomcat-client.jks -srckeystore tomcat-client.p12 -srcstoretype pkcs12 -alias karun-tomcat-client-cert
~$ (optional step) keytool -import -alias root -keystore tomcat-client.jks -trustcacerts -file ~/openssl/CA/certs/karun-tomcat-root-ca.crt

ステップ 4: Tomcat の変更

# Make this change in server.xml of tomcat server
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           keystoreFile="/opt/tomcat/openssl-certs/tomcat-server.jks"
           keystorePass="password"
           keyAlias="karun-tomcat-server-cert"
           truststoreFile="/opt/tomcat/openssl-certs/tomcat-server.jks"
           truststorePass="password"
           clientAuth="true" sslProtocol="TLS" />

ステップ 5: Tomcat サーバーを再起動してログをチェックし、起動時にエラーがないことを確認します

ステップ 6: クライアント証明書をブラウザにアップロードする

ブラウザー (例: Firefox) で、[設定] -> [詳細設定] -> [証明書] -> [証明書の表示] -> [証明書] に移動します。

「tomcat-client.p12」をインポート

https://<tomcat ip>:8443/

参考文献

http://pages.cs.wisc.edu/~zmiller/ca-howto/

http://www.area536.com/projects/be-your-own-certificate-authority-with-openssl/

于 2016-08-09T22:42:30.430 に答える
-1

次の手順を試します

  1. 8443 で構成したとおりにコンテナーをスプールします。
  2. -Djavax.net.debug=SSL を使用してクライアント アプリケーションを実行します。

そのコマンドは大量の情報をスプールします。それを確認する必要があるのは、サーバーが相互認証のために受け入れる CA のリストを提示していることです。リストされた CA に証明書が含まれていない場合、クライアントはサーバーに一致するものを見つける方法がわかりません。

これは、openssl コマンド 's_client' を使用して、はるかに簡単に行うことができます。

openssl s_client -connect localhost:8443 -showcerts

これにより、これをデバッグする価値が計り知れない情報がフォーマットされます。

サーバーが「受け入れ可能な」CA のリストを提示しない場合は、証明書セットを作成するときにいくつかの魔法を行う必要があります。

あなたが見つけたことを教えてください。うまくいけば、あなたを正しい方向に導くことができます.

OPは追加情報を追加しました

わかりましたので、次はあなたにとって少し問題です:

---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 263 bytes
---

2つのことがすぐに飛び出す

  1. サーバーにピア証明書がありません
  2. クライアント CA 名がリストされていません

したがって、(1)の場合:

  1. keytool を使用して、実際にキーストアに別名「tomcat」があることを確認してください。
  2. tomcat のストア/キー パスワードは間抜けです。健全性のために、keystorePassword と keyPassword の両方の属性を同じ値でコネクタに追加してください。Tomcat 7のドキュメントでは、keystorePass が設定されていない場合、デフォルトで keyPass になることが示されています。keyPass と keystorePass が同じ場合は、keyPass 属性のみを設定します。

(2) については、まず (1) を機能させる必要があります。

于 2014-12-08T19:28:19.010 に答える