TLS 1.2 ECDHE_RSA签名 [英] TLS 1.2 ECDHE_RSA signature

查看:381
本文介绍了TLS 1.2 ECDHE_RSA签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发Java TLS服务器。我正在尝试让以下CipherSuite工作:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

I'm currently working on a Java TLS server. I'm trying to get the following CipherSuite to work : TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

当我使用openssl s_client测试它时,在ServerKeyExchange消息之后出现以下错误:

When I test it using openssl s_client I get the following error after the ServerKeyExchange message :


140735242416208:错误:1414D172:SSL
例程:tls12_check_peer_sigalg:错误的签名类型:t1_lib.c:1130:

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

以下是Wireshark中显示的TLS消息

Here is the TLS message as seen in Wireshark

握手在decode_error致命错误时失败。

The Handshake fails on a decode_error fatal error.

所以我猜客户端不喜欢选择的签名算法。

So I guess the client doesn't like the signature algorithm chosen.

但我现在只使用默认的SignatureAndHashAlgorithm,因为 RFC 5246 Section-7.4.1.4.1

But I am only using the default SignatureAndHashAlgorithm for now as per RFC 5246 Section-7.4.1.4.1


如果协商密钥交换算法是(RSA,DHE_RSA,
DH_RSA,RSA_PSK,ECDH_RSA,ECDHE_RSA)之一,表现得好像客户已经发送
值{sha1,rsa}。

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}.

(我仍在检查客户端是否确实提供了这些默认值)

(I'm still checking if the client do offer theses default values though)

因为我正在做ECDHE_RSA我相信我应该根据RFC 4492第5.4节哈希并签署serverECDHparams(这里的第一篇帖子只有2个链接抱歉:))

Since I'm doing ECDHE_RSA I believe I should hash and sign the serverECDHparams as per RFC 4492 Section 5.4 (First post here so only 2 links sorry :) )

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;

我应该按照RFC 2246第7.4.3节

And I should do this as per RFC 2246 Section 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);

关于签署serverParams的Java代码:

My Java code regarding signing the serverParams :

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));
}

所以我的问题基本上是:我错了这一切吗?如果是的话,我做错了什么?

So my question is basically : Am I wrong about all this ? and if so, what am I doing wrong ?

谢谢你的时间! :)

推荐答案

这又是我,我似乎已经解决了我注意到的两件事:

It's me again, I seem to have fixed my particular problem 2 things I noted :


  1. 关于我的Java代码,MessageDigest类只进行哈希没有签名,所以我现在使用Signature类。

  2. 看起来我只需要在TLS1.2中使用SHA1签名我根本不需要做MD5。

  1. Regarding my Java code, the MessageDigest class only does hashing no signing so I now use the Signature class instead.
  2. It seems I only need to sign using SHA1 in TLS1.2 I don't need to do MD5 at all.

第二项是我应该在RFC中找到的但没有(可能它写在某处,我不知道)我认为这对人们有用,即使他们没有做Java;)

The second item is what I should have found in the RFC but didn't (maybe it is written somewhere, I don't know) I think this could be useful for people even if they're not doing Java ;)

我的代码现在看起来如何:

How my code looks now :

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从客户提供的列表中使用。但是您可以将其修改为仅使用SHA1withRSA进行响应,因为这似乎是默认的HashAndSignatureAlgorithm。

The code is different because in between I added a function to choose the SignatureAndHashAlgorithm to use from the list the client provides. But you could modify this to only respond using SHA1withRSA as this seems to be the default HashAndSignatureAlgorithm.

这篇关于TLS 1.2 ECDHE_RSA签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆