How does browser generate symmetric key during SSL handshake - ssl

I have a small confusion on SSL handshake between browser and server in a typical https web scenario:
What I have understood so far is that in the process of SSL handshake, client (browser in this case) encrypts a randomly selected symmetric key with the public key (certificate received from server). This is sent back to the server, server decrypts it (symmetric key) with the private key. This symmetric key is now used during rest of the session to encrypt/decrypt the messages at both the ends. One of main reasons to do so is given as faster encryption using symmetric keys.
Questions
1) How does browser pick and generates this "randomly" selected symmetric key?
2) Do developers (or/and browser users) have control on this mechanism of generating symmetric keys?

Here is a very good description of how HTTPS connection establishment works. I will provide summary how session key is acquired by both parties (client and server), this process is known as "a key agreement protocol", here how it works:
The client generates the 48 byte “pre-master secret” random value.
The client pads these bytes with random data to make the input equal to 128 bytes.
The client encrypts it with server's public key and sends it to the server.
Then master key is produced by both parties in following manner:
master_secret = PRF(
pre_master_secret,
"master secret",
ClientHello.random + ServerHello.random
)
The PRF is the “Pseudo-Random Function” that’s also defined in the
spec and is quite clever. It 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 hash
functions. Half of the input is sent to each hash function. It’s
clever because it is quite resistant to attack, even in the face of
weaknesses 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”.

Quoting from a this great video on network video, minute 1:18:07
Well where do you get randomness on your computer because your
computer is a deterministic device?
Well it collects entropies like your mouse stroke movements, your key
stroke movements and the timing of your hard disk, it tries to collect
all that randomness from the universe into a pull so that it can generate random keys just for one connection [this session]. And if that randomness is broken and its happened many times
in the last 30 years, then none of this works. If the adversary can
figure what your randomness can be then they can guess your keys. So use good randomness.
Note: the keys are created per session.

Related

How are the random numbers in SSL obfuscated to prevent a third party from generating the same master key?

My understanding of how SSL works:
The client sends a hello message containing the SSL version number, supported key, cipher and hash methods, and a randomly generated number.
Server replies selecting the key, cipher and hash methods, a randomly generated number, and its certificate.
Client and server generate a master key based on above randomly generated number(s).
Client request change cipher, server replies change cipher, and they are now both encrypted with the master key.
My question is that wouldn't a third party (eg man in the middle) be able to intercept the initial hello messages, use the intercepted randomly generated numbers and figure out the master key, and thereby able to figure out what the rest of the messages are for the entirety of the connection? Thanks!
SSL can encrypt your message and traffic.
If man in the middle able to intercept, he'll see an encrypted message but not danger because that's hash function a way.
Good luck!
By #Jackie

in TLS/SSL, what's the purpose of staging from premaster secret to master secret and then to encryption keys? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Why don't client and server just exchange the encryption keys directly using public key encryption or DH key exchange protocol? What the rationale behind that or what the problem it is to solve?
Its helpful to understand how keys are derived in modern SSL/TLS. Things were a bit different in early SSL (like SSLv2).
The master_secret is a common secret shared by the client and server. It is used to derive session specific keys. The master_secret derived form other parameters (discussed below).
There are 6 each secrets derived from the master_secret:
Client encryption key
Server encryption key
Client MAC key
Server MAC key
Client IV
Server IV
Assuming that neither eNULL nor aNULL is used, both the client and server use an encryption key for confidentiality and a HMAC key for authenticity. Each (client and server) has its own key.
While IVs are usually considered public, SSL/TLS treats them as secret parameters.
From RFC 5246, the master_secret is derived as:
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
The pre_master_secret comes from key agreement or key transport. If it comes from key agreement, then the pre_master_secret is the result of Diffie-Hellman key agreement. In an agreement scheme, both parties contribute to the derived secret.
If the pre_master_secret comes from a key transport scheme, then the client encrypts a random value under the server's public key. In this scheme, only the client provides keying material. When only one party provides the key, its called a key transport scheme.
What the rationale behind that or what the problem it is to solve?
The first stage, where the pre_master_secret is used, provides a "pluggable" architecture for key agreement or key transport.
The second stage, where the master_secret is derived, ensures both the client and server contribute to the keying material.
In addition, there's a label - "master secret" - that helps ensure derivation is unique even if the same parameters are used for something else (assuming a different derivation uses a different label). Use of labels are discussed in SP800-56 and SP800-57 (among other places).
The hash used in the second stage, where the master_secret is derived, performs two functions. First, it performs a mixing function. Second, it maps elements in the group used by key exchange or key agreement into random bit patterns.
The final stage is the derivation of the 6 keys from master_secret. According to 6.3. Key Calculation, the derivation does not provide key independence. It just ensures interoperability:
To generate the key material, compute
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.server_random +
SecurityParameters.client_random);
until enough output has been generated. Then, the key_block is
partitioned as follows:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
The steps above are a solid design. However, when used in SSL/TLS, there are lots of devils running around. For example, the above is not enough when a feature like renegotiation is added (triple handshake attack ftw!).
I believe the reason is that if the client simply selected a random number to use as the symmetric key and encrypted it using the server's public key to send to the server, there would potentially be a vulnerability if common clients used an imperfect random number generator, leading to predictable symmetric keys and making the communications much easier to break.
The actual key exchange protocol ensures that the symmetric key contains randomized elements from both the client and the server. This means that even if the client has an imperfect random number generator, the communications are still protected if the server's random number generator is cryptographically strong. Even if both the client's and the server's random number generators have weaknesses, the attack against the combination of the two is likely to be more expensive than if only the client's random number generator were used.
The rationale is that if the secret key is never exchanged it can never be detected. Key negotation algiorithms are known to be secure. An encryption is only as secure as its key.
pre master key to master key:
one side random is not really random, but 2 side 3 times random number could be really random..
master key to 6 key pairs:
2 for encryption, 2 for message integration check, and 2 for preventing CBC attack

Securing a UDP connection

For a personal MMO game project I am implementing a homebrew reliable UDP-based protocol in java. Given my current setup I beleive it would be relatively simple for a snooper to hijack a session, so in order to prevent this I am taking the opportunity to learn a little cryptology. Its very interesting.
I can successfully create a shared secret key between the client and server using a Diffie-Hellman key exchange (a very clever concept), but now I need to use this to guarantee the authenticity of the packets. My preliminary testing so far has shown that the couple of different ciphers Ive tried bloat the amount of data a bit, but I would like to keep things as small and fast as possible.
Given that I am only trying to authenticate the packet and not nessecarily conceal the entire payload, I have the idea that I could put an 8 byte session ID generated from the secret key into the packet header, encrypt the whole packet, and hash it back down to 8 bytes. I take the unencrypted packet and put the 8 byte hash into the place of the session ID and then send it off.
Would this be secure? It feels a little inelegant to encrypt the whole packet only to send it unencrypted - is there a better/faster way to achieve my goal? Please note I would like to do this myself since its good experience so Im not so interested in 3rd party libraries or other protocol options.
If both peers have access to a shared secret (which they should, since you're talking about Diffie-Hellman), you could simply store a hash of the datagram in its header. The receiver checks to see if it matches.
As an added security measure, you could also add a "challenge" field to your datagram and use it somewhere in the hashing process to prevent replays.
So this hash should cover:
The shared secret
A challenge
The contents of the datagram
EDIT
The "challenge" is a strictly incrementing number. You add it to your datagram simply to change the hash every time you send a new message. If someone intercepts a message, it cannot resend it: the receiver makes sure it doesn't accept it.

AES encryption how to transport IV

I understand that unique IV is important in encrypting to prevent attacks like frequency analysis. The question: For AES CBC encryption, whats the importance of the IV? has a pretty clear answer explaining the importance of the IV.
Would there be any security holes in sending the IV in clear text? Or would it need to be encrypted with the same public/private key that was used to send the symmetric key?
If the IV needs to be sent encrypted, then why not generate a new symmetric key each time and consider the IV as part of the key? Is it that generating a symmetric key is too costly? Or is it to minimize the amount of data transported?
The top answer to Secret vs. Non-secret Initialization Vector states:
A typical key establishment protocol will result in both involve parties computing a piece of data which they, but only they, both know. With Diffie-Hellman (or any Elliptic Curve variant thereof), the said shared piece of data has a fixed length and they have no control over its value (they just both get the same seemingly random sequence of bits).
How do two entities derive the "same seemingly random sequence of bits" without having a shared piece of information? Is the assumption that the shared information was sent encrypted? And, if the shared information is sent encrypted, why not just send the IV encrypted?
Because an application needs to transport the symmetric key securely, it would seem that separating the IV from the key itself is essentially an optimization. Or am I missing something?
There is no security hole by sending the IV in cleartext - this is similar to storing the salt for a hash in plaintext: As long as the attacker has no control over the IV/salt, and as long as it is random, there is no problem.
The main difference between initialization vector and key is that the key has to be kept secret, while the IV doesn't have to be - it can be readable by an attacker without any danger to the security of the encryption scheme in question.
The idea is that you can use the same key for several messages, only using different (random) initialization vectors for each, so relations between the plain texts don't show in the corresponding ciphertexts.
That said, if you are using a key agreement scheme like Diffie-Hellman, which gives you a new shared secret for each session anyways, you can also use it to generate the first initialization vector. This does not really give much security advantages compared to choosing the initialization vector directly and sending it with the message, but saves some bits of bandwith, and some bits of entropy from your random source. And it makes the IV a bit more random in case that one of the partners has a bad randomness source (though DH is not really secure in this case, too).
How do two entities derive the "same seemingly random sequence of bits" without having a shared piece of information?
Is the assumption that the shared information was sent encrypted? And, if the shared information is sent encrypted,
why not just send the IV encrypted?
Diffie-Hellman is based on a group-theoretic problem: Eve knows a (cyclic) group G with generator g and sees the the two values g^a (transmitted from Alice to Bob) and g^b (transmitted from Bob to Alice), where a and b are random large integers chosen by Alice and Bob, and unknown to Eve and even the other partner). The shared secret is then (g^a)^b = g^(a·b) = (g^b)^a. Obviously Bob (who knows b) can calculate the secret as (g^a)^b, while Alice (who knows a) can calculate (g^b)^a. Eve somehow needs to derive this secret to crack the protocol.
In some groups this (known as the computational Diffie-Hellman problem) seems to be a hard problem, and we are using these groups in Cryptography. (In the original DH, we use a subgroup of prime order of the multiplicative group of some large finite prime field, in Elliptic Curve DH we use an elliptic curve group over a finite field. Other groups work, too (but some of them are weak, e.g. in the additive group of a field it is trivial to solve).)
Then both Alice and Bob use a key derivation function to derive the actual keying material (i.e. encryption keys for both directions, MAC keys, and the starting IVs).

SSL security concern

I'm wondering why ssl encrypted data can't be cracked easily once the packets are intercepted. As i understand it when you connect to a site like facebook the browser and site agree on a cipher, what stops the sniffer from seeing what cipher they agreed to?
SSL uses asymmetric encryption, meaning the decryption key is different than the encryption key. So if you as a client encrypt your packets with the server's public key, it can only be decrypted by the private key, which remains on the server. Of course, this is a simplification of everything that happens in an SSL transaction, but that's the basis of the concept.
Imagine sending a box with an open padlock to the other side - when the other side wants to send a message, they put it inside the box, lock the padlock and send it back to you, where you use your (private) key to unlock it. Even if the intercepting party has sees the padlock, they still don't have the key.
There's a lot of ways to describe it. For me, my ah-hah moment was when I figured out that, after information is encrypted multiple times, it can be decrypted in any order.
A encrypts first, passes to B a single encrypted message [A encryption].
B encrypts the message a second time, and passes to A a double encrypted message [A encryption and B encryption]
A removes [A encryption] from the message, leaving only [B encryption], and sends the message to B.
B now has a [B encrypted] message, and knows how to decrypt it.
The sniffer sees the message encrypted three different ways: [A], [AB], and [B].
That's three message passes to exchange one message, but once it's passed and both sides have the unique information to decrypt further communication, future messages only need one trip.
If you want a simple example of how a message could be decrypted in any order, you can use XOR as a sample encryption method. For keys A and B, message M, and XOR is ^, then
M ^ A ^ A = M
M ^ A ^ B ^ A ^ B = M
Facebook signs it's package with a certificate that Facebook got from an certificate authority such as RapidSLL.
As long as you trust the certificate authorities that all certificate they issue for facebook.com do really belong to facebook.com the connection is safe.
Facebook then sends you via a signed message it's public encyrption key which you can use to encrypt your messages to be read by facebook.
Yes, the cipher is public. However, the client asymmetrically encrypts a random session key (or rather a precursor) using Facebook's public key (they verify it's really Facebook's key by checking that it is signed by someone trusted). So only Facebook (who has a private key) should be able to derive the actual symmetric keys that are used to exchange website data.
See this detailed walk-through. In that example, an eavesdropper can tell that the connection uses RSA, RC4, and MD5. But they don't have Amazon's private key, so they can't derive the session keys.
Like Derek H said, there are fundamental differences between symmetric and asymmetric encryption. Look up stuff like DH key exchange protocol and RSA cipher, they are fundamental in SSL/TLS. On the other hand, it's relatively easy to decrypt sniffed data (ROBOT attack).
If you just need to be sure your communication is secure, you can simply use SSL/TLS Server Test, there you can see if you're not using recommended algorithms or see if your SSL/TLS configuration is PCI-DSS/HIPAA/NIST compliant.