web-dev-qa-db-ja.com

TLSで使用されるプリマスターシークレットはどのように生成されますか?

Helloメッセージで送信されるランダムな値の組み合わせを使用していると思います。 RFC 2246から:(TLSv1.0)

 RSA encrypted premaster secret message

   Meaning of this message:
       If RSA is being used for key agreement and authentication, the
       client generates a 48-byte premaster secret, encrypts it using
       the public key from the server's certificate or the temporary RSA
       key provided in a server key exchange message, and sends the
       result in an encrypted premaster secret message. This structure
       is a variant of the client key exchange message, not a message in
       itself.

   Structure of this message:
       struct {
           ProtocolVersion client_version;
           opaque random[46];
       } PreMasterSecret;

       client_version
           The latest (newest) version supported by the client. This is
           used to detect version roll-back attacks. Upon receiving the
           premaster secret, the server should check that this value
           matches the value transmitted by the client in the client
           hello message.

       random
           46 securely-generated random bytes.

クライアントが以前に送信した値とどのように一致しますか?誰かがこれを説明できますか?ゆうありがとうございます!この値を計算するAPIはありますか?

クライアントは、プロトコルバージョン(2バイト)とクライアントがランダムに生成したいくつかのバイト(46バイト)を連結して、48バイトのプリマスターシークレットを生成します。クライアントは 暗号的に安全なPRNG ;からこれらの46バイトを取得することになっています。実際には、これは、オペレーティングシステムによって提供されるPRNG=(_/dev/urandom_、CryptGenRandom()...)を使用することを意味します。

次に、クライアントは48バイトのプリマスターシークレットをサーバーのRSA公開キー(サーバーが以前にクライアントに送信したCertificateメッセージで)を使用して暗号化します。暗号化された結果は、クライアントがClientKeyExchangeメッセージとしてサーバーに送信するものです。 RSAは健全な非対称暗号化アルゴリズムであるため、サーバーが復号化するものはクライアントが暗号化するものと同じです。

サーバーは、プライベートRSAキーを使用してClientKeyExchangeメッセージの内容を復号化します。その時点で、クライアントとサーバーの両方がプリマスターシークレットを知っています。次に、それを使用してマスターシークレットを計算し(_client_random_および_server_random_を使用)、ClientHelloおよびServerHelloメッセージで以前に交換し、全体をPRF)。マスターシークレットから、再びPRFミキシングを使用して、後続のデータの実際の暗号化キーを取得します。

12
Tom Leek

TLSは複数の鍵交換スキームをサポートしているため、事前マスターシークレットを取得するにはさまざまな方法があります。 TLSは、前のコメントでかなりよく説明されているRSAベースの鍵交換を使用できます。また、DH、DHE、ECDH、ECDHE(diffie-hellman、diffie-hellman with ephemeral keys、楕円曲線diffie-hellman、ecdh with ephemeral keys)も使用できます。それぞれ)。

DHファミリーのアルゴリズムでは、プリマスターシークレットは2つの値のグループから生成されます。

  1. サーバーによって選択されたパブリックプリミティブ
  2. 送信者と受信者の秘密鍵

サーバーは、クライアントが使用する公開プリミティブを秘密鍵と共有して、プリマスターシークレットを作成します。 Diffie Hellmanの場合は、次のようになります。

パブリックプリミティブ

p - a large prime 

g - primitive root modulo p 

秘密鍵:

a - client's private key

b - server's private key

鍵交換:

Server to Client  :  {g, p, (g^b mod p)}

Client Calculates :  (g^b mod p)^a = g^ab mod p

Client to Server  :  (g^a mod p)

Server Calculates :  (g^a mod p)^b = g^ab mod p

注意して見ると、サーバーとクライアントの両方に共通のキー(g ^ ab mod p)があり、これをプレマスターシークレットとして使用できます。

この事前マスターシークレットを [〜#〜] hkdf [〜#〜] に送り、暗号で保護された複数のキーを抽出できます。これらのキーは、セッション暗号化キー、hmacキー(または暗号化暗号に基づくIV)として使用できます。

楕円曲線DHは、pやgなどのプリミティブを使用する代わりに、名前付き楕円曲線を使用します。

他の質問については、

この値を計算するAPIはありますか?

暗号で保護されたランダムな値を意味する場合は、はい、python hasos.urandom(n)

nバイトの暗号を生成するために使用できます。安全なランダム値。

4
harshc