I need to make a secure chat server with end-to-end encryption support, theoretically I know how it works but I don't know how to send an encryption key over ssl.
You should use a proven key exchange algorithm such as Diffie–Hellman.
Otherwise you can rely on asymmetric keys to then exchange a new/temporary symmetric key. For example, each side sends half of a symmetric key which is encrypted with each-others' public key.
Related
I'm building an application and want it to securely transfer data to a server.
Thinking to use public/private keys for initial handshake to encrypt a key with which to encrypt subsequent data.
Is it reasonable to have the private key integrated in the executable which will be distributed out in the wild for anyone to reverse-engineer?
I also thought of using three-pass protocol, but read about some of its weaknesses and it probably won't work for me
I followed Martin's advice and posted to security exchange (https://security.stackexchange.com/questions/158650/distribute-private-key-with-application).
There I received an answer that I accepted, by user Serverfrog:
Generate the Private/Public Keypair on the client, encrypt this with a
password (maybe choose from the User itself).
The send the Public Key encrypted via Server Public Key to the Server
and you have your entire Public/Private Stack.
I am a student and I want to implement Identity based encryption by using c#.
Example: I want to encrypt a message by using receivers email address(Public Key) and sender will send this message to receiver. Once receiver receives this encrypted message, he will decry-pt this message by using his private key.
This looks okay theoretically, but I am struggling to do this practically.
I don't know
how to encrypt a message by using receivers email address
how receiver will decry-pt encrypted message?
how receiver will get his private key?
I am expecting help from this platform, as I already spent a lot of time on searching this.
What I have tried:
I tried encryption and decryption by using RSA algorithm, but the problem here is RSA generates his own public and private key pair. And I can not use receivers email address as a public key to encrypt message.
Thank you in advance.
Ashok
You can generate secure symmetric keys from an email address, any string for that matter, with a key derivation function such as PBKDF2 (aka Rfc2898DeriveBytes).
RSA is asymmetric encryption with separate keys for encryption and decryption, symmetric encryption such as AES uses one key for both encryption and decryption.
Asymmetric encryption such as RSA has the advantage of two keys where the encryption key can be publicly known. But it is very slow and the data size, the keys are large (2048-bits is a currently secure size) and the data length is limited to the key size, it is generally used to encrypt symmetric keys. There is no control over symmetric key pair creation other than length. Use asymmetric encryption only when a public/private key pair must be used.
Asymmetric encryption such as AES is fast, has smaller keys with 128-bits common and secure and can handle data of essentially any length.
Asymmetric encryption solves the trust problem inherent in symmetric encryption by using two different keys: a public key for encrypting messages, and a private key for decrypting messages. This makes it possible to communicate in secrecy with people you don't fully trust. RSA is a cryptosystem for public-key encryption, and is widely used for securing sensitive data.
I checked the dotnetnuke source but I don't know dotnetnuke uses RSA for asymmetric encryption or not?
It would be very helpful if someone could explain asymmetric encryption method in dotnetnuke.
Thanks.
DotNetNuke doesn't use any asymmetric cryptography by itself. It uses some hash functions like MD5 (bad) and SHA-256 as well as symmetric encryption like two-key 3DES (very bad) and AES.
The only thing is that you can configure to use transport security (SSL/TLS) which includes various types of asymmetric cryptography. In SSL/TLS, client and server can negotiate a cipher suite depending on both their capabilities. You need a private key and a certificate (which contains the signed public key) in order for the connection between client and server to be encrypted.
Our clients call our web service over SSL and authenticate themselves with a username and password. Our server then generates a symmetric key and sends it back to the client.
Then, the client establishes a TCP connection to our server, and sends a login message. At this point, I want to authenticate the client.
My idea is to have the client encrypt a well-known/static piece of text with the symmetric key and use this as proof that it is in possession of the key.
Since the symmetric key is generated randomly, is it ok that I use a static piece of text here?
Any input appreciated.
SSL is built to authenticate both client and server, and asymmetric cryptography the most secure primitive you can use in this scenario. Symmetric ciphers can be used for authentication by using a Cipher Block Chaining Message Authentication Code other wise known as CBC-MAC mode. The use of CBC-MAC has similar protection as an HMAC, but utilizing a symmetric cipher instead of a message digest function. CBC-MAC mode is used by WPA to protect wireless networks.
Your idea is subject to a replay attack - if someone observes a user logging in, they can store the static-text-encrypted-with-symmetric-key and use it later to authenticate themselves.
The accepted way of doing this is a challenge/response. The client connects, the server generates a random challenge and sends it to the client, and the client responds with the encrypted version of the challenge (although you should actually use a HMAC here, rather than a block cipher, because otherwise your client is effectively a one-block decryption oracle!). It would also be safer to use two different random keys (provided at the same time over the web service), one for encryption and one for authentication.
Note though that this scheme, as written, is still susceptible to a man-in-the-middle attack. You are definitely better off using SSL, as The Rook suggests. This will require your client to generate a public key and send it to the web service. The web service responds with a signed certificate containing the client's public key along with the client's unique identifier (username, or whatever) in the DN field. The server on the separate connection verifies the client certificate used (ensuring it's signed by your web service), and verifies that the client identifier in the certificate matches the client that is asking to connect.
I'm currently developing a system to transmit data between client and server, and was wondering what the strength of the encryption I planned to use was.
My thought was to have a private/public RSA key pair and hand out the public key to each client (leaving the private key solely on the server). Each client would then generate their own AES key and RSA encrypt it. They would then AES encrypt their data and send the encrypted data and encrypted AES key to the server. The server would then decrypt the AES key using the private key, and then decrypt the data using the AES key.
Are there any security flaws I am missing and/or is there a better way to do this?
This is almost exactly how SSL/TLS works (check out the handshake section). The only thing to make it stronger is to generate the AES key for each connection, rather than using the same key each time. You might also want to digitally sign messages that go back and forth to avoid man-in-the-middle and other spoofing attacks.
Generally speaking, creating a good cryptosystem is very difficult. When possible, you should always favor an existing (trusted) application to help out. In this case, you might consider sending your messages using HTTPS, rather than creating your own system.
You should give us more information about the language and platform you are using, so that we can give you specific recommendations about libraries that already exist and wich will handle the details for you. Using cryptographic primitives directly is not trivial and difficult to get exactly right, and with cryptography, you have to be "not exactly right" only once for your security to be broken.
To answer your question, it's generally a better idea to create a session secret (the AES key) through a Diffie-Hellman exchange, and each side use its private RSA key to sign its key-exchange data.
Otherwise, if the session secret is not established through a DH exchange, an adversary that gains access to the private RSA key (which has to be stored somewhere) could decrypt all traffic that was ever sent between the client and server.
If the secret is established through a DH exchange, then only the authentication part of the protocol would be exposed. Although an adversary in possession of the private RSA key would then not be able to read any previous communication, he still could either enter an authenticated dialog with the client/server or launch a man-in-the-middle attack (which may or may not be easily done, depending on the network).
One vulnerability would be if an attacker substituted their public key for the "real" public key. Then they would be able to intercept traffic as a "man-in-the-middle."
Protocols like S/MIME, PGP, and TLS use RSA encryption to transport keys just as you propose. However, the public keys they use are in certificates signed by trusted authorities.
The integrity of these trusted authorities must be carefully protected. For example, they might be burned into a tamper-proof hardware token, or a MAC might be computed over them using a password.
I'm not sure your approach will protect anything! You're going to keep the private key on the server and the public key will be distributed. If I get a hold of your public key, I'll be able to interact with your server at will. I think you should reverse the key ownership; each client will hold it's-own private key and the server will have a list of public keys (ala SSH). The server will have to add 'authorized' public keys and only to holders of the private keys will be able to connect.
Hope this helps.