Client server AES encryption - aes

I am developing a client server application in which data is transferred between two clients through the server.
The data should be encrypted and I thought of using AES.
My thought was to use PBKDF2 in order to derive the AES key from the client's password.
In this case the client will encode the data, the server will decode it, reencode it using the 2nd client's password and send it to the 2nd client.
Do you think this is the best way to implement this?
Is there a way for the first client to encode and the 2nd client to decode without server interference?
How can I encrypt the AES key and transfer it from one client to the other?
What do you think of the following solution?
Client and server create a private AES key using Diffie-Hellman (this key is specific to each client).
Transmitting client creates a session AES key and encodes it using the private AES key.
Server decrypts the session key and re-encrypt it for every client in the session (using each client's private key).
Transmitting client encrypts the data using the session AES key and sends it to the server.
Server sends the data to all recipient clients without any required processing.

You could also use Diffie–Hellman key exchange. What programming language do you use?

You could use an asymmetric encryption algorithm to send the AES key securely and then use this key for symmetric AES encryption/decryption. The communication could go like this:
A client wants to talk to a server with encrypted messages.
The client generates a pair of public/private keys and sends the public key to the server.
The server uses the public key to encrypt some secret key and sends it back to the client.
The client uses his private key to decrypt the secret (both now know the secret key to encrypt/decrypt their communication).
The client uses AES with the secret key to encrypt the message he wants to send to the server.
The server uses the secret key to decrypt the message.

You must create your own protocol for communating part of your program first or use available secure protocols such as HTTPS.the only thing that i can tell you is that heavy computing operations such as encryption/decryption must be passed by clients first and then server process reliable requests.

Related

Public and Private Keys - Clients/Server Communication

So Currently, I am trying to understand public/private keys with servers and clients work.
Overall, I am trying to set up a server (Socket Stream) storing all messages which will show up encrypted on the server side.
When a user connects through entering the port and its username, through the client application, any message intended for this user will show while the messages which arent will stay encrypted. These messages will all be sent to the client side from the server which is storing it currently.
So lets say Alice wants to messages Pami secretly, Pami's public key will be used to encrypt the message while alice's private key will be used for the signature.
For this, will encryption be done on the server side and decryption on the client side or does both occur on the same side?

Encrypted chat protocol

I am in the process of creating a flutter application that will include direct messaging. You can message 1 person or a group of people. I want this to all be encrypted for privacy.
The method I was thinking about is to do a hybrid RSA, AES system. On signup, a RSA key pair would be generated and the public key would be sent to the database for storage. Then when the user wants to message someone, they would request the other persons public key and create a AES-256 key for encrypting any messages. Then when the user wants to send the message it will be encrypted with AES and the AES key will be encrypted with RSA, so that the receiver can decrypt the message.
The problem I am facing is that I want the user to be able to sync the messages across devices. I had the idea of generating the public and private keys from a mnemonic phrase and then using that for recovery.
However this doesn’t solve the AES recovery issue. I am unsure if storing the AES key in the database for each chatroom is secure, even if it is encrypted with RSA. An encrypted AES key for each person involved in the chat would have to be stored.
If anyone has any recommendations or tips please let me know.

Trouble understanding how JWTs are used with RSA (Man in the middle attack?)

I'm having trouble understanding how exactly JWTs are used in conjunction with RSA encryption. This is my current understanding for RSA:
-The client logs makes a post request to the server with his credentials, if the credentials are valid the server signs a JWT using the private key and sends it to the client.
-The client uses the public key to verify the JWT came from the server and then stores this JWT for future requests.
Now does the client just attach this JWT to the header of each get/post request I make to protected routes in order to verify the user? Wouldn't this be vulnerable to a man in the middle attack since they could easily change the contents of the request and the server would have no way to know it's been modified. How am I supposed to hash the header + payload to stop an entity from changing the data like with HMAC?
The critical piece of information/understanding you seem to be missing here is that JWTs contain a checksum, which is a hash dependent on the contents of the JWT. The server will sign every JWT with its private key before it sends it back to the client, including a checksum. Upon receving an incoming JWT, the JWT will again compute the checksum based on the contents and compare to the checksum which the token itself contains. In the event of a man-in-the-middle attack, which attempted to insert or alter the contents of the JWT, the checksum computed would not match the value embedded in the JWT. You might ask next what would prevent the man-in-the-middle from also computing the correct checksum. Well, MITM can't do that, not without having the server key. The hash should largely be impossible to reverse engineer out the key used to sign it. So as long as you defend your server key from being hijacked, the JWT pattern can actually be very secure.

Understanding RSA signing for JWT

I'm implementing a sign in system with the help of the JWT (JSON Web Token) scheme. Basically, after a user sign in / login, the server signs a JWT and passes it to the client.
The client then returns the token with each request and the server verifies the token before sending back a response.
This is pretty much how you would expect it, but I'm having some problems with the logic of the process. From all the mathematical articles I've read, it seems that RSA signing uses asymmetric keys for signing. As the public key, as its name suggests, is exposed to the client and the private key is kept on the server, it makes sense to sign the JWT with the public key which is sent to the client and verify it on the server side using the private key.
However, on every example and library I see it seems to be the other way around. Any idea as to why it is so? If a JWT is signed with the private key and verified with the public one than whats the point?
First off, apologies, this answer got rather long.
If you use RSA to sign your tokens, and a connecting client is a web browser, the client will never see the RSA keys (public or private). This is because the client presumably doesn't need to verify that the JWT is valid, only the server needs to do that. The client just holds onto the JWT and shows it to the server when asked. Then the server checks to make sure its valid when it see's the token.
So why might you need a public / private key combo for JWT's? Well first off, you don't need to use a public / private key algorithm.
You can sign JWT's with a number of different algorithms, RSA being one of them. Other popular choices for signing your JWT's are ECDSA or HMAC algorithms (the JWT standard supports others as well). HMAC, specifically, is not a public / private key scheme. There's just one key, the key, which is used to both sign and validate the tokens. You can think of this as using the private key for both signing and validating the JWT's. I'm not an expert on this by any means, but here's the conclusions I came to from doing my own research recently:
Using HMAC is nice because it's the fastest option. However, in order to validate the JWT's, you need to give someone the one key that does everything, Sharing this key with someone else means that that person could now also sign tokens and pretend like they're you. If you're building multiple server applications that all need to be able to validate your JWT's, you might not want every application to have the ability to sign tokens as well (different programmers might be maintaining the different applications, sharing the signing ability with more people is a security risk, etc). In this case, it's better to have one, tightly controlled private key (and one app that does the signing) and then share the public key around with other people to give them the ability to validate the tokens. Here, the private key is used for signing the tokens, and the public key is used for validating them. In this case you'd want to choose RSA or ECDSA.
As an example, you might have an ecosystem of apps that all connect to
the same database. To log users in, each app sends folks to one,
dedicated, 'logging in' app. This app has the private key. The other
apps can verify that the person is logged in using the public key (but
they can't log people in).
The research I've done points to RSA being the better option for most JWT apps in this scenario. This is because your app will be, theoretically, validating tokens frequently. RSA is much faster then ECDSA at verification. ECDSA is primarily nice because the keys are smaller in size. This makes it better for HTTPS certificates because you need to send the public key to the client's browser. In the JWT scenario though, the keys are staying on a server so the storage size is n/a and the verification speed is more important.
Conclusion: if you're building a small app without multiple smaller 'micro-service apps' / you're the only developer, probably choose HMAC to encrypt your keys. Otherwise, probably choose RSA. Again though, I'm not an expert, just someone who recently googled this topic, so take this with a grain of salt.
There is a difference between signing/verifying and encrypting/decrypting data but the semantics can be similar.
You sign data with a private key that only controlled sources have so anyone who receives the information can use your public key to validate this information was indeed sent by you and is the same information you intended to send out.
You encrypt data with a public key and decrypt with a private key. This sounds opposite but really follows the same logical concept as signing. If you want to send data between person A and person B, both people have a public/private key pair and they share their public keys with each other when they meet (handshake). A constructs a message for B and encrypts it using B's public key and sends it to B. Now, no one without B's private key can decrypt that message including A - even though they originally sent it.
In terms of JWT, a JWT payload by itself is just Base64 encoded JSON with some standardized fields. The signature allows someone with the public key to validate the information hasn't been altered by someone in the middle. Similar to a checksum but with some extra security based warm fuzzy feelings. The contents of the signed JWT are easily visible (base64 is encoding like unicode or utf-8, not encryption) to the end user and anyone in the middle which is why it is generally frowned upon to send sensitive data in a JWT like passwords or PII.
As others have mentioned, most JWTs contain information not intended for clients but to help facilitate the stateless part of RESTful services. Commonly, a JWT will contain an accountid, userid and often permissions as "claims". An API endpoint can verify the signature and reasonably trust the claims to not be altered by the client. Having the client send the JWT for each request saves the endpoint having to do a lot of database back and forth just to get where they are by simply verifying a signature with a public key.
Additionally, signed JWTs can be encrypted. According to the JWE spec, the payload is encrypted after signing and then decrypted before verifying. The trade off here is that all endpoints must also have the private key to decrypt the JWT but end users won't be able to see the contents of the JWT. I say trade off because in general private keys are meant to be kept secure and a widely distributed private key is just less secure. Security, risk assessment and cost/benefit of encryption is a whole other beast :)
Your suggestion:
it make sense to sign the JWT with the public key which is sent to the
client and verify it on the server side using the private key.
is not correct. Signing is done with the private key of the sender, encryption is done with the public key of the receiver. That is how PKI works in general.

How to deliver private keys for later decryption safely?

I'm developing the set of applications, that provide the possibility to read encrypted data between several users using email messages.
It's rather hard... If to compare email messaging with the live chatting (IMs) through single server (for live chatting, I need just chanell with TLS). because I need to decrypt the the message, which is just saved on remote server.
Also, as I suppose the secure server mustn't keep private keys, because the user wants to be sure, that event supplier side (backend) can't decrypt content. Private keys must store on some stuff like smart-cards (which only user has).
For emails, I've found two options:
S/MIME
OpenPGP
So... the main problem (for me) is how to distribute private data, which will allow to decrypt email message for the user, which received the encrypted email message.
So, question is about correct distribution of private keys, right now I can't imagine how to deliver it in secure way.
Private keys are, well, private. You don't want to be transferring them. Never.
Instead, re-think the problem in terms of distributing the public keys in the other direction. Then you don't need to worry about eavesdropping (but you will want to be concerned with authenticity).
The proper approach is to use asymmetric cryptography to secure the data. In this scenario your users send each other their public key, and they can do this in any way. Private keys remain on user's side. The sender encrypts the data with the public key of the recipient, the recipient uses the private key to decrypt the data.
If you absolutely must use symmetric algorithms and keys for encrypting the data, then you still can use asymmetric cryptography to deliver symmetric keys in encrypted form (this is what S/MIME and OpenPGP would do for you, actually).
Note: when I am talking about encryption with a public key, I mean a hybrid scheme, when the data is encrypted with a symmetric session key, which is then encrypted with a public key. The data are almost never encrypted with asymmetric cryptography directly, without employing a symmetric algorithm.