I have a general question about the right handling of sensitive data.
Use case scenario
A user sends sensitive data (documents or images) via an API to a Node.js server. The server then stores the data on the IPFS.
Currently the server is used in order to encrypt and decrypt the data, so that the plain text isnt stored and available on the IPFS. For encryption I am using a combination of AES and RSA similar to this example.
Questions
Would encryption with AES alone be sufficient, since hybrid encryption of AES and RSA is not really used in this case?
Should I add an additional layer of security between the client and the server (hybrid encryption, session key ...) or is a standard HTTPS connection sufficient in this case?
Any other tips or best practices I should consider? (I am not an security expert)
EDIT
Requirements and important points
The application is supposed to create licenses for uploaded Content. For this reason, the uploaded content should be secure and accessible only to authorized persons.
A person is authorized to view content if a corresponding license is available (can be queried by the system).
User experience and simplicity is important aswell
So I think a proper balance of security and usability would be ideal. Complexity or financial costs don't matter at first.
In principle, a user should not have to possess a private key. Therefore, I thought that hybrid encryption might be appropriate if an HTTPS connection is not "secure enough". My understanding would be that the server has a private and public key. When the client connects, the server tells the client the public key. Then the client generates a key for symmetric encryption (e.g. AES) and encrypts it with the server's public key. In this way, the key can be decrypted by the server and both parties have the AES key. This key can then be used to send encrypted content to the server and decrypt it there. The decrypted content can then be re-encrypted and stored on the IPFS.
Thanks in advance.
Related
I am developing a document sharing application that allows users to send files securely. Currently, I encrypt documents on the server side using encryption (key, IV), then encrypt the key and IV with the recipient's public key. However, I want the encryption to be client-side to avoid man-in-the-middle attacks.
I am aware that storing all the information (public key, private key, IV, etc.) on the server side can make my application vulnerable to a data breach, so I am looking for an end-to-end encryption solution.
I am new to this and was wondering if there are any libraries or security protocols I could use to implement this end-to-end encryption method.
What would be the best approaches to implement end-to-end encryption for my application? Are there any specific libraries or security protocols that I could use to enhance the security of my application?
Thank you in advance for your help and advice.
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 reading SSL security logic articles. I am confused a bit. Server has private key and server sends client public key. An encrypted data with public key only can be decrypted by private key.
1- Client side has not a private key. How does client solve the server data?
2- if public key sending over internet, somebody can Access the key who listened the network.
3- encrypt and decrypt should have an algorithm. Do all browsers knows that algorithm? if browser companies knows that encrypt algorithm, this is a security problem.
The public and private keys aren't used for data encryption in SSL. They are only used in the authentication phase. That's why the client doesn't need a private key, unless the server requires client authentication. The actual encryption is done via symmetric encryption using a negotiated session key.
There are resources on the Internet that state otherwise, notoriously the Linux Documentation Project page. They are wrong. The normative reference is RFC 2246.
Your remark about knowing the encryption algorithm is quite incorrect. First, the client has to know the algorithm to be able to encrypt and decrypt. Second, it was established many years ago that security-by-obscurity simply does not work. True cryptographic security comes from well-designed and well-tested algorithms, however well-known they may be, and key length.
A client need to be authenticated by the server, so it need to send credentials. The credentials can be stored in a client database as in encrypted form. Since the server's certificate is known, in order to provide best security the client can use the public key of the server to encrypt the password. But the problem is now how to send the password without double encryption.
For example, suppose the server's authentication URL is "https://example.com/a?u=user&p=password", so the client have to send the SSL-encrypted data of this string to the server. Since the client stores only the encrypted password, it must find a way to send ssl_encrypt("https://example.com/a?u=user&p=")+pre_encrypted_password as a whole to the server.
The client is using WinHTTP api, so are there any way to achieve this?
No. SSL does not work that way - data sent over an SSL connection is encrypted using a symmetric cryptographic algorithm (usually AES, RC4, or similar), using a key that is established during the initial SSL handshake. The public/private key of the server are only used during the initial handshake; after that, they are not used.
Anyways, storing the password this way does not make it any more secure. If it's stored in an encrypted form that can be sent to the server, anyone who managed to get it would be able to use it that way; that encrypted form is password-equivalent, so it's no better than just storing the password!
Potentially you can save the certificate sent by the server (assuming that this certificate has RSA key which allows encryption), then use it in PKCS#7 encryption of your data, and send the encrypted data to the server. There's another question that appears - does the server-side code have access to the certificate. This is not the case in many configurations. So the server won't be able to decrypt the data.
Also, as pointed by EJP, this does not make much sense as you will be double-encrypting the data with merely the same key (technically keys will be different but the added security level will be minimal).
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.