Here is a relevant question: With OpenSSL and ECDHE, how to show the actual curve being used?


openssl s_client -msg -connect google.com:443 -cipher ECDHE-RSA-AES128-SHA

I got something like:

<<< TLS 1.2 Handshake [length 014d], ServerKeyExchange
0c 00 01 49 03 00 17 41 04 1b cf 0c 41 e4 3a b7 ...

I've gone through the TLS document but still can't figure out the meaning of all bytes. So far as I understand, the structure is

0c (meaning it's server key exchange message) +
00 01 49 (the message length) +
03 (named_curve) +
00 17 (curve 23) +
41 (point length) +
04 (uncompress point format) +
1b cf...32 (64byte, point coordinate) +
06 01 01 00 (what's this?) +
58 1d...8a (256byte, RSA signature)

I'm wondering what the 06 01 01 00 part is for.

  • $\begingroup$ This could fit in security.stackexchange.com $\endgroup$ Commented Jun 17, 2015 at 14:09
  • $\begingroup$ the "06 01" is the signature algorithm (SHA-512 and RSA in this case). I'd guess that "01 00" is part of the signature. $\endgroup$ Commented Jun 17, 2015 at 16:06

1 Answer 1


This is what openssl s_client -trace says:

Received Record
  Version = TLS 1.2 (0x303)
  Content Type = Handshake (22)
  Length = 333
    ServerKeyExchange, Length=329
        named_curve: secp256r1 (P-256) (23)
        point (len=65):     048301F0D9E4151ED0414A9F2883216C91ACA3E24FE5C01D69408B495696CAB1A68B8C1ED0906280690E2D533D1BBC2A077D6A389BCA563CAF41712BF2ACCB701D
      Signature Algorithm sha512+rsa (6+1)
      Signature (len=256): 52CDCC60B0D8D23BC678648E073D8AA37BFB7806F762EAFF940CFB2B5A47A7AE1F805632C2F42755DE6B000395F62597EB9998824DA392765FD46D9B99030ACB9A37ACB09071DF5EDEC35E5A6A9F90D96CAAFB2695DF5729C0738EBD68E7356B5FBF5604A643FE224763D04D3302059A0B12BF162A1DB1CFD9DCE10963DAF712FC1A3B425302F9EAA57F30B8C42C66D9E628AFA24E8FF3606D704CB7D2BA630C9DF6DB3675D25B2737B84C192DC1EFFE78612F17B5E0601028BCAD8363C93FBCD08DCCAAEF165C5841856EF4DE99A0FBC9718E5FFE37B584A41D8D63EEEFBC27EA765F36E311647FCB2411AB0E88C51871829396D20F1C234072F98DBC5A490F

With -cipher 'ECDHE+ECDSA' I get:

Received Record
  Version = TLS 1.2 (0x303)
  Content Type = Handshake (22)
  Length = 147
    ServerKeyExchange, Length=143
        named_curve: secp256r1 (P-256) (23)
        point (len=65): 04E90371BC07690CDF28F539B65B7F5680693FDF2EDE9844DE91FB372BC6CFA78DF1F78B7130F862300253BE57314DF78E5D72879DFB772B80569A48B2905FCD57
      Signature Algorithm sha512+ecdsa (6+3)
      Signature (len=70): 3044022031C0D9F942D5DCB4537E94C3E9269628C2A71674648DE3800E16AE63BACB9B8D022079FDB5C8404ED1851B5D91E1DCE987D0D5CF8C05824BA3959B0AD3E77259B1B4

The explanation is in:


A digitally-signed element is encoded as a struct DigitallySigned:

  struct {
     SignatureAndHashAlgorithm algorithm;
     opaque signature<0..2^16-1>;
  } DigitallySigned;


  enum {
      none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
      sha512(6), (255)
  } HashAlgorithm;

  enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }

  struct {
        HashAlgorithm hash;
        SignatureAlgorithm signature;
  } SignatureAndHashAlgorithm;


enum { dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa
        /* may be extended, e.g., for ECDH -- see [TLSECC] */
       } KeyExchangeAlgorithm;

struct {
      select (KeyExchangeAlgorithm) {
          case dh_anon:
              ServerDHParams params;
          case dhe_dss:
          case dhe_rsa:
              ServerDHParams params;
              digitally-signed struct {
                  opaque client_random[32];
                  opaque server_random[32];
                  ServerDHParams params;
              } signed_params;
          case rsa:
          case dh_dss:
          case dh_rsa:
              struct {} ;
             /* message is omitted for rsa, dh_dss, and dh_rsa */
          /* may be extended, e.g., for ECDH -- see [TLSECC] */
  } ServerKeyExchange;

     For non-anonymous key exchanges, a signature over the server's
     key exchange parameters.

If the client has offered the "signature_algorithms" extension, the
signature algorithm and hash algorithm MUST be a pair listed in that


enum { ec_diffie_hellman } KeyExchangeAlgorithm;

      select (KeyExchangeAlgorithm) {
          case ec_diffie_hellman:
              ServerECDHParams    params;
              Signature           signed_params;
} ServerKeyExchange;

select (SignatureAlgorithm) {
          case ecdsa:
              digitally-signed struct {
                  opaque sha_hash[sha_size];
} Signature;

        SHA(ClientHello.random + ServerHello.random +

  A hash of the params, with the signature appropriate
  to that hash applied.  The private key corresponding to the
  certified public key in the server's Certificate message is used
  for signing.

NOTE: SignatureAlgorithm is "rsa" for the ECDHE_RSA key exchange
algorithm and "anonymous" for ECDH_anon.  These cases are defined in

SignatureAlgorithm is "ecdsa" for ECDHE_ECDSA.

SHA in the above template for sha_hash accordingly may denote a
hash algorithm other than SHA-1.
  • 1
    $\begingroup$ And to complete one detail, opaque signature<0..2^16-1> means signature is a TLS "vector" that starts with a 2-octet bigendian length prefix. The "01 00" called out in the question is the length prefix 256 for the RSA signature value, which is just a bigendian integer. $\endgroup$ Commented Jun 18, 2015 at 11:54
  • $\begingroup$ I'm seeing a similar server key exchange message, but without the "06 01" (signature algorithm). Everything else is byte-for-byte identical to the message listed, except of course the ECDHE key values. This seems to happen when I disable the "signature hash algorithm" (0x000d) client hello extension. $\endgroup$
    – juhraffe
    Commented Oct 6, 2015 at 2:54
  • $\begingroup$ @juhraffe I think you see TLS version before 1.2. See RFC 5246 Section 7.4.3 "Note that the introduction of the algorithm field is a change from previous versions". Also see openssl code, e.g.: github.com/openssl/openssl/blob/master/ssl/t1_trce.c#L664 SSL_USE_SIGALGS is true only if TLS1.2 was negotiated. $\endgroup$
    – Z.T.
    Commented Oct 7, 2015 at 20:53
  • $\begingroup$ @Z.T. You're right, the version is TLS 1.0 when I see the missing algorithm field. Thanks for the pointer to the RFC and openssl code. $\endgroup$
    – juhraffe
    Commented Oct 9, 2015 at 4:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.