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ミキシングを使用して、後続のデータの実際の暗号化キーを取得します。
TLSは複数の鍵交換スキームをサポートしているため、事前マスターシークレットを取得するにはさまざまな方法があります。 TLSは、前のコメントでかなりよく説明されているRSAベースの鍵交換を使用できます。また、DH、DHE、ECDH、ECDHE(diffie-hellman、diffie-hellman with ephemeral keys、楕円曲線diffie-hellman、ecdh with ephemeral keys)も使用できます。それぞれ)。
DHファミリーのアルゴリズムでは、プリマスターシークレットは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バイトの暗号を生成するために使用できます。安全なランダム値。