Diffie-Hellman in place of SSL? - encryption

Can a Diffie-Hellman key exchange algorithm be used to encrypt client-server communication on a web-page in place of SSL? If it can, what are the disadvantages (i.e. why does the standard use SSL which requires a certificate authority)? My understanding is that Diffie-Hellman can be used to secretly establish a shared key which then can be use to encrypt any further communication.

The two aren't really comparable. DH is a key-exchange algorithm, nothing more and nothing less. SSL attempts to establish that the server you're connecting to is really who it says it is. To do that, it uses a certificate that can be traced back to somebody you (are supposed to be able to) trust.
DH, by itself, only keeps others from reading the transmitted data. SSL is intended to establish considerably more than that (but can use DH to keep others from reading the stream).
Just for an obvious example, using DH (by itself) a Man in the middle attack is fairly simple. If I can get you to connect to my server instead of the one you intended to, I can use DH to establish a "secure" session with you. I then connect to the server you originally intended to. Every packet I get from you, I decrypt, re-encrypt with a key I used to connect to that server, and send on to that server. I do the same with all its response packets. To you, everything looks like it came directly from the original server, and the purchase you made (for example) works just like normal. The only thing that changes is that I also store your credit card number, and when you try to fill your car with fuel the next day, the charge is declined, because in the meantime I've spent all your credit.
The authentication in SSL is at least intended to prevent that from happening. If your browser tried to connect to (for example) www.amazon.com, it should give you a warning if my SSL certificate doesn't specify that it was issued to www.amazon.com -- and a CA shouldn't issue such a certificate to anybody but Amazon.
DH, by itself, doesn't really even guarantee most of what I've said above. By itself, DH is just a way to exchange a key (or, perhaps it could be phrased as "exchange information necessary for both parties to create identical keys, without ever exchanging the key itself in the clear"). After both parties have the key, they can (and presumably will) use it to encrypt/decrypt data -- but that encryption is actually separate from DH itself.

Actually Diffie-Hellman is a part of SSL.
But one part does not replace others.
From here SSL Diffie-Hellman is used for:
This a Diffie-Hellman key exchange in
which the server's certificate
contains the Diffie-Hellman public
parameters signed by the certificate
authority (CA). That is, the
public-key certificate contains the
Diffie-Hellman public-key parameters.
The client provides its Diffie-Hellman
public key parameters either in a
certificate, if client authentication
is required, or in a key exchange
message. This method results in a
fixed secret key between two peers,
based on the Diffie-Hellman
calculation using the fixed public
keys.

You can use anonymous Diffie-Hellman key agreement with SSL. This provides privacy on the channel, but no authentication.
Of course, without authentication, you really can't have privacy, because your private channel could be connected to a "man-in-the-middle". That's why the anonymous DH cipher suites are discouraged.
If the lack of a certificate is stopping you from using SSL where it's really needed, get a free one from startcom.org.

Diffie-Hellman key exchange is only for keyexchange. It does not give you authenticitation (who you're talking to), you need certificates and a PKI for that.
So yes you can do encryption, but you dont know with who you're talking to

The DH key exchange cannot, of itself, do encryption. It is used to establish a session key, but not to do the encryption. So, at this level, the question is mis-stated or reveals either lack of precision or lack of understanding (I suspect precision is the problem this time).
The question is:
Do you want to encrypt data with anybody at all?
Do you want to be sure who you are talking to?
As already pointed out, SSL uses a DH key exchange to establish a session key. However, it also ensures that the program on the other end is someone you trust (directly or indirectly). If you don't need to worry about whether the other person is trustworthy, you could just use a simple DH key exchange and then send encrypted data without needing certificates. But you won't be sure who you are talking to unless you validate that - and the certificates used by SSL etc helps with that validation.

Related

Qt Crypto - How to validate RSA key?

I'm trying to use the Qt Cryptographic Architecture to generate public/private key pairs for nodes, and want to have a protocol in which nodes confirm that a message came from a given source (public key) by issuing a challenge to ensure they are the owners of the corresponding private key. I'm a little stuck on the actual syntax for QCA though ...
This should get me a private key, from which I can also get the public key:
QCA::KeyGenerator generator;
QCA::PrivateKey privateKey = generator.createRSA(1024);
Does QCA already have some sort of challenge protocol built in? If so, how can I use it? If not, how can I apply some of the standard cryptographic challenge protocols using these keys? I'm really just trying to demo a simple security concept - I'm not looking for anything complicated or even particularly robust.
Also, this is a side question, but since I don't need encryption, should I be opting for DSA as opposed to RSA?
There are more than one of doing that. But since all clients already have their asymmetric key pairs you may deploy two-way TLS in establishing connection.
In this scheme both client and server allow establishing connection only, if they trust certificates (public keys) of each other. This guarantees client authentication and non-repudiation.
From your side you will need to provision server certificate to all clients and all client certificates to the server. To avoid dealing with certificate authorities, certificates could be self-signed.
QCA has examples for TLS client and server.

Simple password authentication in TCP client server architecture

Good morning everyone.
I've been reading (most of it here in stack overflow) about how to make a secure password authentication (hashing n times, using salt, etc) but I'm in doubt of how I'll actually implement it in my TCP client-server architecture.
I have already implemented and tested the methods I need (using jasypt digester), but my doubt is where to do the hashing and its verification.
As for what I read, a good practice is to avoid transmitting the password. In this case, the server would send the hashed password and the client would test it with the one entered by the user. After that I have to tell the server if the authentication was successful or not. Ok, this won't work becouse anyone who connect to the socket the server is reading and send a "authentication ok" will be logged on.
The other option is to send the password's has to the server. In this case I don't see any actual benefit from hashing, since the "attacker" will have to just send the same hash to authenticate.
Probably I'm not getting some details, so, can anyone give me a light on this?
The short answer to your question is definitely on the side that permanently stores the hashes of the passwords.
The long answer: hashing passwords only allows to prevent an attacker with read-only access to your passwords storage (e.g. database) from escalating to higher power levels and to prevent you knowing the actual secret password, because lots of users use same pass across multiple services (good description here and here). That is why you need to do the validation on the storage side (because otherwize, as you've mentioned, attacker would just send "validation ok" message and that's it).
However if you want to implement truly secure connection, simple passwords hashing is not enough (as you've also mentioned, attacker could sniff TCP traffic and reveal the hash). For this purpose you need to establish a secure connection, which is much harder than just hashing password (in web world a page where you enter your pass should always be served over HTTPS). The SSL/TLS should be used for this, however these protocols lie on top of TCP, so you might need another solution (in common, you need to have a trusted certificate source, need to validate the server cert, need to generate a common symmetric encryption key and then encrypt all data you send). After you've established secure encrypted connection, encrypted data is useless to sniff, the attacker would never know the hash of the password.

Is TLS over TLS possible?

Would it be possible to establish a TLS connection over TLS with OpenSSL or some other tool?
If possible, would the certificates for each level need to be different?
This should work just fine in theory, though I cannot say for sure whether OpenSSL or something would support it easily. You can technically use the same certificate for multiple TLS connections, even if one is nested inside another.
However, I want to point out that one common reason to nest TLS connections might be to tunnel data over a multi-layered encrypted connection, making some subset of the data available at each stop in the tunnel (i.e. peeling back a layer of the encryption). Using the same certificate doesn't really support that use case. Perhaps you've got another use case in mind.
Furthermore, it is cryptographically sound to encrypt encrypted data. That is, more encryption cannot make data less secure. Lastly, encrypting encrypted data alone will not make it more secure. That is, AES(AES(x,key1),key2) where key1 != key2 is not more (or less) secure than AES(x, key1). Just in case that was your motivation.
TLS doesn't care what data you're sending and receiving, so it could well be another TLS session (though I've no idea why you'd want to do that).
Since it's another, independent session, there's no reason you wouldn't be able to use the same certificate.
ths tls rfc has confirmed such situation, and the answer is yes, please refer to this : https://www.rfc-editor.org/rfc/rfc5246, I couldn't find which part has mentioned this, but I remember I have read it.

how encryption works

Hi
I know a basic rules on https!
I know there is private & public key, and public key is for encryption and private key is for decryption!
Now I have questions:
* - IF I know the public key why I cannot decrypt data, Surely it's related to private key!!!
*- And does https protocol encrypt all data or only data that sent by client??
for emxample, If i go to gmail.com, html codes are encrypted or not?
now if answer is yes(and HTML codes are encrypted) how my browser can decrypt it and others can't??
If no, why we should use it for example for downloading backup of important data?
Okay, a couple of points of confusion here.
First, HTTPS isn't actually encrypted with a public/private key scheme -- technically, "asymmetric encryption." It's instead encrypted using a symmetric encryption -- one of several, actually -- with a session key that's established through an algorithm like Diffie-Hellman key exchange.
The result is that the encryption is carried out through a one-use key that's computed as part of the handshake setting up the SSL connection.
The Wikipedia article on Transport Layer Security (SSL was really a proprietary term from Netscape) is reasonably decent.
If you could get that key, you could indeed decrypt the data, but since the usual key now is 128 bits long, you have roughly 1 chance in 2128 of getting it right -- or, in another way of looking at it, you can expect to take about 2127 (170141183460469231731687303715884105728) tries before you'd find the key.
But second, asymmetric encryption does come in one way, however. When you're establishing an SSL connection, the host provides an X509 certificate to identify itself; that's so someone can't hijack DNS and make themselves appear to be paypal.com instead of Vlad's Cut Rate Hacking. The X509 certificate is signed using a public/private key pair: the signature is hashed using the private side of a trusted providers key -- say VeriSign. They provide the public side, which allows you to confirm that the certificate was indeed encrypted by VeriSign. That confirms the authenticity of the cert.
Public Key encryption systems are based on One Way Functions; functions that are far easier to compute in one direction than in the other. There are two common choices of one-way functions for public-key cryptography systems: Large integer factorization and Discrete Logarithms.
There are no mathematical proofs that large integer factorization doesn't have easy solutions: however, several decades of intense research hasn't found any polynomial-time algorithms. (Not that one would necessarily be fast, just that finding one has been a good long-term goal.) The RSA cryptosystem safety is based on the difficulty of factoring large primes.
There are mathematical proofs that solving discrete logarithms is very difficult. The El Gamal and Diffie-Hellman algorithms rely on discrete logarithms for their safety.
The public key mechanisms are only part of actual deployed solutions though. Public Key systems are usually used for digital signatures and for negotiating a session key that is used with a symmetric cipher. Symmetric ciphers are far faster, much safer to use on plain text with patterns, and are an integral portion of modern communications privacy and integrity.
Now, to directly address your questions :)
IF I know the public key why I cannot decrypt data, Surely it's related to private key!!!
They are related. And you could find one given the other. But the computational complexity of finding one is currently so much worse than generating new public / private key pairs, the key itself should have no value by the time you have cracked it. (Years for 'smaller' keys, probably millennium for 'larger' keys. Trouble is, the definition moves around. :)
And does https protocol encrypt all data or only data that sent by client?? for emxample, If i go to gmail.com, html codes are encrypted or not?
HTTPS itself encrypts everything in both directions. HOWEVER, some web sites will use unencrypted http for images, css, javascript, and https for the HTML that actually contains the user data. This is because serving unencrypted content is much faster than serving encrypted content. It is also very unsafe, because most of those types of contents can be replaced while in-flight, allowing intruders to modify the browser's DOM or inject other new code, that lets them get access to the private data. Most browsers complain about mixed SSL/TLS and unencrypted content, so hopefully not many sites do this.
how my browser can decrypt it and others can't?
During the SSL/TLS handshake at the start of the session, the server and browser negotiate a new session key that will be used for the session. All the traffic between browser and client are encrypted with the session key, and as a result of the way the SSL/TLS session is created, only the client and server know the key:
https://www.rfc-editor.org/rfc/rfc5246#page-64
8.1.1. RSA
When RSA is used for server authentication and key exchange, a 48-
byte pre_master_secret is generated by the client, encrypted under
the server's public key, and sent to the server. The server uses its
private key to decrypt the pre_master_secret. Both parties then
convert the pre_master_secret into the master_secret, as specified
above.
8.1.2. Diffie-Hellman
A conventional Diffie-Hellman computation is performed. The
negotiated key (Z) is used as the pre_master_secret, and is converted
into the master_secret, as specified above. Leading bytes of Z that
contain all zero bits are stripped before it is used as the
pre_master_secret.
Note: Diffie-Hellman parameters are specified by the server and may
be either ephemeral or contained within the server's certificate.
IF I know the public key why I cannot
decrypt data, Surely it's related to
private key!!!
Yes the are related, but to determine the private key from the public one would require solving a computational hard problem that is factorize a prime large number.
For telling it in simple words, you can do it, but the time it would require with the actual technologies is too long.

Best practices for encrypting continuous/small UDP data

I am having an application where I have to send several small data per second through the network using UDP. The application needs to send the data in real-time (no waiting). I want to encrypt these data and ensure that what I am doing is as secure as possible.
Since I am using UDP, there is no way to use SSL/TLS, so I have to encrypt each packet alone since the protocol is connectionless/unreliable/unregulated.
Right now, I am using a 128-bit key derived from a passphrase from the user, and AES in CBC mode (PBE using AES-CBC). I decided to use a random salt with the passphrase to derive the 128-bit key (prevent dictionary attack on the passphrase), and of course use IVs (to prevent statistical analysis for packets).
However I am concerned about few things:
Each packet contains small amount of data (like a couple of integer values per packet) which will make the encrypted packets vulnerable to known-plaintext attacks (which will result in making it easier to crack the key). Also, since the encryption key is derived from a passphrase, this will make the key space way smaller (I know the salt will help, but I have to send the salt through the network once and anyone can get it). Given these two things, anyone can sniff and store the sent data, and try to crack the key. Although this process might take some time, once the key is cracked all the stored data will be decrypted, which will be a real problem for my application.
So my question is, what are the best practices for sending/encrypting continuous small data using a connectionless protocol (UDP)?
Is my way the best way to do it? ...flowed? ...Overkill?
Please note that I am not asking for a 100% secure solution, as there is no such thing.
You have several choices. You can use DTLS, which is a version of TLS adapated for datagrams. It is specified in an RFC and implemented in the openssl library. You can also use the IKE/IPsec protocol and use a UDP encapsulation of the IPsec portion. Usually IPsec is available at the OS level. You can also use OpenVPN, which looks to be a hybrid of TLS for key exchange and a proprietary UDP-based packet encryption protocol.
If your problem is that the data is too small, how about extending the data with random bytes? This will make the plaintext much harder to guess.
This question is a little old, but what about using a One Time Pad type approach? You could use a secure reliable transport mechanism (like HTTPS) to transmit the one time keys from the server to your client. There could be two sets of keys -- one for client to sever, and one for server to client. Each datagram would then include a sequence number (used to identify the one time key) and then the encrypted message. Because each key is used for only one datagram, you shouldn't be exposed to the small data problem. That said, I'm not an expert at this stuff, so definitely check this idea out before using it...
Use Ecdh key exchange (use a password to encrypt the client private key; left on the client) instead of a password. This is a very strong key.
Aes cbc does not help you; the messages are too short and you want to prevent replay attacks. Pad your 64 bit message (two integers) with a counter (starting with 0) 64 bits means 2^64 messages can be sent. Encrypt the block twice (aes ecb) and send e(k;m|count)|e(k;e(k;m|count)). Receiver only accepts monotonically increasing counts where the second block is the encryption of the first. These are 32 byte messages that fit fine in a udp packet.
if 2^64 messages is too small; see if your message could be smaller (3 byte integers means the counter can be 80 bits); or go back to step 1 (new private keys for at least one side) once you are close (say 2^64-2^32) to the limit.
You could always generate a fresh pair of IVs and send them alongside the packet.
These days a good streaming cipher is the way to go. ChaCha20 uses AES for a key stream. Block ciphers are the ones that need padding.
Still that's only part of the picture. Don't roll your own crypto. DTLS is probably a mature option. Also consider QUIC which is emerging now for general availability on the web.
Consider using ECIES Stateless Encryption https://cryptopp.com/wiki/Elliptic_Curve_Integrated_Encryption_Scheme where you sending devices use the public key of the central system and an ephemeral key to generate a symmetric key pair, then a KDF, then AES-256-GCM. You end up with modest size packets which are stateless and complete. No need for an out-of-band key agreement protocol.
There are good examples on the internet, for example: https://github.com/insanum/ecies/blob/master/ecies_openssl.c
I am using such a system to deliver telemetry from mobile devices over an unsecure channel.

Resources