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 3 years ago.
Improve this question
I have developed my own system similar to ssl and at the moment im using this key exchange method:
Server generates a RSA public-private key pair and sends public key to client
client generates an AES key and encrypts using servers public key and sends to the server
the server decrypts and now both ends have a shared secret key
I just want to know if this is secure and if there are any proper methods out there.
No, it's not secure. Specifically, it's vulnerable to a man-in-the-middle attack, where an eavesdropper hijacks the connection between the client and server.
+--------+ +---------+ +--------+
| | <---(RSA pub key B)---- | | <---(RSA pub key A)---- | |
| CLIENT | | M.I.T.M | | SERVER |
| | -------(AES key)------> | | -------(AES key)------> | |
+--------+ +---------+ +--------+
To the client, the man in the middle behaves just like the server. It sends the client an RSA public key (RSA pub key B) and receives an AES key from the client. What it can then do is contact the server to obtain a genuine RSA key (RSA pub key A) from the actual server, and send it the same AES key.
Since the man in the middle now has the AES key, it can read all the traffic between the client and server.
As others have hinted in the comments, your first mistake occurred here:
I have developed my own system similar to ssl
Don't do that. Use existing cryptosystems and protocols. Don't invent your own.
In this case, you should be using HTTPS/TLS.
in partial answer to your question:
I just want to know if this is secure
you should note that nothing "is secure". The best you can do is not being "vulnerable" to existing/well-known/published attacks, and hoping that nobody has any attacks they're keeping secret that you'd be vulnerable to.
Learning by experimenting can be good, but reading up on existing attacks can be a better use of time. Here are a few potentially relevant links:
https://www.crypto101.io/, via https://diagprov.ch/crypto-reading-list.html which has lots of other suggestions
https://www.rfc-editor.org/rfc/rfc7457 contains a summary of known attacks on TLS, while https://www.rfc-editor.org/rfc/rfc5246 describes TLS1.2 and discusses security issues throughout
https://cve.mitre.org/cve/ documents published vulnerabilities and it might be useful to have a look at a few
in answer to:
if there are any proper methods out there
yes, lots. You just need to be much more specific. Why/what is preventing you from using SSL/TLS at the moment?
Related
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
I've been experimenting with RSA encryption in python (cryptography.hazmat.primitives.asymmetric). I have the following setup: On one end is the client with the public key sending encrypted data back to the server, which holds the private key. Right now I've got one-directional encryption working, but I'm wondering how you would (or if you should) securely decrypt a message client-side. I thought about just encrypting the private key and storing it, but then the password would appear in the code and expose the key to compromise. Is there a way to securely implement this with a key exchange? Or--the most likely alternative--is this a misuse of the protocol?
EDIT: Wanted to clarify that the possible concerns here would be that using RSA in this way might expose the private key on the file system or between the server and the client.
The normal way is for the server to encrypt the reply with the client's public key and client decrypt with its private key. This requires TWO RSA keypairs -- one for the client and one for the server, and requires each end to know the other's public key.
This need (along with high cost of PKE compared to symmetric encryption) is why PKE is normally only used for authentication and/or key exchange, and a symmetric cipher is used to actually encrypt traffic.
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
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am currently working on a web API. I need to ensure that the message sent from client to server is security enough (cannot be modified, read by attacker and able to identify the clients).
I have a preliminary design here. Is it secure enough?
I decided to make use of PKI. That is,
Both server and clients have a set of RSA public and private keys.
The server also have a database to store the client IDs and their public keys.
Before client and server communicate, they establish the session key using diffie-hellman key exchange. The "secret" used in diffle-hellman is the private key. The messages sent will be encrypted by the sender's private key. So, the receiver can identify the sender by using sender's public key, and man-in-the-middle attack is prevented. Then a session key K is established.
Then the client send a message to server:
Client send: Client ID, E(K, message), H(K, E(message), ClientID)
where H() is the hash function of SHA256.
When the server receives the message, it calculate H(K, E(message), ClientID) and compare it with the HMAC received. If they are equal, then the message should be secured.
I know that my design cannot prevent replay attack. But I am not considering it at this stage. Is my design secure enough? Any comment will be greatly appreciated. Many thanks!
Like you wrote, the first thing I thought about is a replay attack. You can prevent it by adding timestamp or counters to the messages (such that every two messages are different).
Additionally, notice that you still have to worry about the how to distribute the public keys.
If you do it over the Internet, so without Certificate Authority (CA) - you might be exposed to MitM attack when you try to get the public key!
The problem of getting some authentic key is crucial, and in my opinion - this is the main problem that SSL comes to deal with (it does so using CAs). Encryption and authentication given authentic symmetric key is easy! (using encryption and MAC)
Additional thing:
What is H? hash function or HMAC? both are different things!
You wrote: H(K, E(message), ClientID). If you refer H as MAC (MAC has a key) and K is the key, it is better to use different keys for the MAC and the encryption. If not - I don't think you should send hash/MAC on your key.
And two last things:
Someone can just contact the server many times (each time as new client) and causes DoS attack.
Why do you save the public key of the client? In the first (hopefully secure) connection, where the server first knows the client, you can create the symmetric key and save it! It shorter and much more efficient.
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.