jspωiki
Master Secret

Overview#

In TLS, the Master Secret is the Symmetric Key used for Encryption between the Protocol Client and Protocol Server.[1]

For all Key-Exchange methods, the same algorithm is used to convert the Premaster Secret into the Master Secret. The Premaster Secret should be deleted from memory once the Master Secret has been computed.

The Master Secret is always exactly 48 bytes in length. The length of the Premaster Secret will vary depending on Key-Exchange method.

The Premaster Secret is the secret value we sent ClientKeyExchange. The Master Secret is simply a string whose ASCII bytes (e.g. "6d 61 73 74 65 72 ...") are used. We then concatenate the random values that were sent in the ClientHello and ServerHello.

The PRF is the "Pseudorandom function" that's also defined in the TLS specification and is quite clever. The Pseudorandom function combines the secret, the ASCII label, and the seed data we give it by using the keyed-Hash Message Authentication Code (HMAC) versions of both MD5 and SHA-1 Cryptographic Hash Functions.

Half of the input is sent to each Cryptographic Hash Functions. It's clever because it is quite resistant to attack, even in the face of Cryptographically Weak in MD5 and SHA-1. This process can feedback on itself and iterate forever to generate as many bytes as we need.

Following this procedure, we obtain a 48 byte Master Secret of

4C AF 20 30 8F 4C AA C5 66 4A 02 90 F2 AC 10 00 39 DB 1D E0 1F CB E0 E0 9D D7 E6 BE 62 A4 6C 18 06 AD 79 21 DB 82 1D 53 84 DB 35 A7 1F C1 01 19

Generating Lots of Keys#

Now that both sides have a Master Secret, the spec shows us how we can derive all the needed session keys we need using the PRF to create a "key block" where we will pull data from:
key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random + SecurityParameters.client_random);

The bytes from "key_block" are used to populate the following:

client_write_MAC_secret[SecurityParameters.hash_size]
server_write_MAC_secret[SecurityParameters.hash_size]
client_write_key[SecurityParameters.key_material_length]
server_write_key[SecurityParameters.key_material_length]
client_write_IV[SecurityParameters.IV_size]
server_write_IV[SecurityParameters.IV_size]

Since we're using a stream Cipher instead of a block Cipher like the Advanced Encryption Standard AES, we don't need the Initialization Vectors (IVs). Therefore, we just need two Message Authentication Code (MAC) keys for each side that are 16 bytes (128 bits) each since the specified MD5 hash digest size is 16 bytes. In addition, the RC4 cipher uses a 16 byte (128 bit) key that both sides will need as well. All told, we need 2*16 + 2*16 = 64 bytes from the key block.

Running the Pseudorandom function, we get these values:

client_write_MAC_secret = 80 B8 F6 09 51 74 EA DB 29 28 EF 6F 9A B8 81 B0
server_write_MAC_secret = 67 7C 96 7B 70 C5 BC 62 9D 1D 1F 4A A6 79 81 61
client_write_key = 32 13 2C DD 1B 39 36 40 84 4A DE E5 6C 52 46 72
server_write_key = 58 36 C4 0D 8C 7C 74 DA 6D B7 34 0A 91 B6 8F A7

More Information#

There might be more information for this subject on one of the following: