2016-07-07 25 views
2

現在、Java TLSサーバーで作業しています。私は、次のCipherSuiteが仕事に取得しようとしている:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHATLS 1.2 ECDHE_RSA署名

を私は、OpenSSL s_clientを使用してテストするとき、私はServerKeyExchangeメッセージの後に次のエラーを取得する:Wiresharkの中で見られるように、ここで

140735242416208:error:1414D172:SSL routines:tls12_check_peer_sigalg:wrong signature type:t1_lib.c:1130:

は、TLSメッセージです The TLS message as seen in Wireshark

致命的なエラーdecode_errorでハンドシェイクが失敗します。

だから、クライアントは選択した署名アルゴリズムが気に入らないと思います。

しかし、私は唯一の私がECDHE_RSAをやっているので

を(クライアントはしかし論文のデフォルト値を提供していますかどうかはまだ確認しています)RFC 5246 Section-7.4.1.4.1

If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}.

ごとに今のデフォルトSignatureAndHashAlgorithmを使用しています私は

ServerKeyExchange.signed_params.sha_hash 
     SHA(ClientHello.random + ServerHello.random + 
              ServerKeyExchange.params); 
struct { 
    select (KeyExchangeAlgorithm) { 
     case ec_diffie_hellman: 
      ServerECDHParams params; 
      Signature signed_params; 
    }; 
} ServerKeyExchange; 

そしてI(第:)ので、ここで残念にのみ2のリンクを掲載)私はRFC 4492あたり5.4節としてserverECDHparamsをハッシュし、署名しなければならないと考えていますRFCあたり2246節serverParamsに署名について7.4.3

select (SignatureAlgorithm) { 
    case rsa: 
     digitally-signed struct { 
      opaque md5_hash[16]; 
      opaque sha_hash[20]; 
     }; 
} Signature; 


md5_hash 
MD5(ClientHello.random + ServerHello.random + ServerParams); 

sha_hash 
SHA(ClientHello.random + ServerHello.random + ServerParams); 

私のJavaコードとしてこれを実行する必要があります。

private byte[] getSignedParams(ChannelBuffer params) 
     throws NoSuchAlgorithmException, DigestException, 
     SignatureException, InvalidKeyException { 
    byte[] signedParams = null; 
    ChannelBuffer signAlg = ChannelBuffers.buffer(2); 
    MessageDigest md5 = MessageDigest.getInstance("MD5"); 
    MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
    switch (session.cipherSuite.sign) { 
     case rsa: 
      signAlg.writeByte(2); // 2 for SHA1 
      sha.update(clientRandom); 
      sha.update(serverRandom); 
      sha.update(params.toByteBuffer()); 
      md5.update(clientRandom); 
      md5.update(serverRandom); 
      md5.update(params.toByteBuffer()); 
      signedParams = concat(md5.digest(), sha.digest()); 
     break; 
    } 
    signAlg.writeByte(session.cipherSuite.sign.value); // for RSA he byte is one 
    ChannelBuffer signLength = ChannelBuffers.buffer(2); 
    signLength.writeShort(signedParams.length); 
    return concat(signAlg.array(),concat(signLength.array(),signedParams)); 
} 

だから私の質問は基本的には次のとおりです。私はすべてこのことについて間違っているのですか?もしそうなら、私は間違って何をしていますか?

ありがとうございました! :)

+0

私はあなたのプログラミング関連の疑問のためのstackoverflowフォーラムでこの質問を投稿することをお勧めします。あなたはすぐに答えを得るかもしれません。 – Limit

+0

ありがとう、よく私はこれが純粋に私を理解していない問題、RFCsだと思った。私はそれ以来、(?)回答と私はそれを人々のために後で見つけるためにそこに投稿します:) – Alpha4

+0

あなたが5246 7.1.4.1から引用したテキストは、 "クライアントがsignature_algorithms拡張子を送信していない場合、"となります。 openssl s_client **は**拡張機能を送信します。あなたのトレースでClientHelloを見てください。しかしそれには0201 SHA1 + RSAが含まれているので、その理由でこのシグネチャを拒否しないでください。しかし、あなたの署名は間違っています。 MD5 + SHA1 + RSA署名はTLS 1.0(2246)および1.1(4346)では使用されますが、サーバ選択のハッシュで標準PKCS1-v1_5に1.2変更されます。 1.246の相違点一覧の2番目の項目と5246 4.7を参照してください。 –

答えて

0

それは再び、私は指摘2つの物事私の特定の問題を修正しているように見える私です:私のJavaコードについて

  1. をするMessageDigestクラスはだけなので、私は今の代わりに署名クラスを使用して何の署名をハッシュないし。
  2. TLS1.2でSHA1を使用して署名する必要があるようですが、私はMD5をまったく行う必要はありません。

2番目の項目は、私がRFCに見つかりましたが(多分それがどこかに書かれている、私は知らない)私は、これはそうでない方にも人々のために有用であることができるとは思わなかったしているべきですJavaの実行;)

私のコードは、今どのように見えるか:

private byte[] getSignedParams(ChannelBuffer params) 
     throws NoSuchAlgorithmException, DigestException, 
     SignatureException, InvalidKeyException { 
    byte[] signedParams = null; 
    Signature signature = Signature.getInstance(selectedSignAndHash.toString()); 
    ChannelBuffer signAlg = ChannelBuffers.buffer(2); 
    signAlg.writeByte(selectedSignAndHash.hash.value); 
    signature.initSign(privateKey); 

    signature.update(clientRandom); 
    signature.update(serverRandom); 
    signature.update(params.toByteBuffer()); 

    signedParams = signature.sign(); 

    signAlg.writeByte(session.cipherSuite.sign.value); 
    ChannelBuffer signLength = ChannelBuffers.buffer(2); 
    signLength.writeShort(signedParams.length); 
    return concat(signAlg.array(), concat(signLength.array(), signedParams)); 
} 

をコードが原因の間で異なっている私は、クライアントが提供するリストから使用するSignatureAndHashAlgorithmを選択する機能を追加しました。しかし、デフォルトのHashAndSignatureAlgorithmと思われるので、SHA1withRSAを使用してのみ応答するようにこれを変更できます。

関連する問題