Encrypt something on a server without decryption key available - encryption

say you have some string:
bank_account = '12345';
and you want to encrypt it automatically with some method:
magic_encrypt(bank_account);
and store it. The decryption password/code will not exist on the server, and so the server needs to be able to encrypt it the data without being able to decrypt it. This way if the server is compromised, none of the stored data would be able to be decrypted by an evil 3rd party.
The data, when needed, would be pulled from the server and decrypted in a secure environment.
What type of encryption should I use?

What you want is called asymmetric key cryptography. Algorithms like RSA and ElGamal will do that.

Related

Is it secure to pass static value for CryptoJS AES encryption key?

I want to encrypt all my form data with crypto js AES encryption. Is it good to keep the encrypt key value in client side like below.Kindly suggest.
var key = CryptoJS.enc.Utf8.parse("234234234DFDFDF343434DFDFDF")
, iv = CryptoJS.enc.Utf8.parse("234234324234324")
, data = CryptoJS.enc.Utf8.parse(str)
, encryptedData = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
No, this is generally not secure.
First of all, you wrongly state your goal. AES encryption is not a goal, it is a means to an end. What you want to do is to keep your form data confidential. The form data is called "the message" in crypto terminology.
If you need to send your message to a server, and then let the server have the decrypted form, then you need transport security. It's best to use TLS for that. Commonly JavaScript doesn't have any means to create a trust relationship with the server (your browser uses it's certificate store with trusted certificates for that). So in that case you cannot rely on JavaScript security.
Sometimes you want to keep your front end from decrypting the messages. In that case you could send a public key such as an RSA public key over the secure channel. Then you could encrypt the form data using RSA and AES (hybrid cryptography). Your backend would then be able to decrypt the messages. This scheme still fails if your front end sends the wrong key though, as the message would be encrypted with a public key from another party. So this assumes that the front end software cannot be easily hacked (or replaced altogether by a different server, subverting the traffic).
Even if you could use a trusted AES key then using CBC for transport mode security will definitely enable plaintext or padding oracle attacks. You're lacking way too much experience with crypto to pull this off. Use TLS, that's hard enough (to secure, using it is relatively easy).

Access symmetric key generated by EVP_Seal/EVP_Open functions?

I'm trying to set up a bidirectional encryption scheme between a client and server using the OpenSSL crypto API.
I have generated an RSA public/private key pair for the server. I wanted to use the EVP_Seal/Open functions to generate a symmetric key to be used for session encryption. The client uses the public key to encrypt a symmetric key and send it to the server using EVP_Seal. The server then uses EVP_Open to decrypt messages... but how do I now encrypt messages to send back to the client?
I don't actually have access to unencrypted the symmetric key, so I can't make calls to EVP_EncryptInit and the like. How do I encrypt information to send back to the client? I was under the impression I was generating a bi-directional symmetric key with these functions, but I can't figure out how to use it.
I considered sending a second symmetric key that I just generate myself (using, say, RAND_bytes) as a "message" that the server could then decrypt, but it seems like I should be able to use the symmetric key that was already generated instead of making a new one.
I also considered using the encrypted symmetric key output from EVP_Seal as my actual symmetric key and passing that as the message for the server to use for encryption, but that also seemed really weird and incorrect.

Understating use of Salt with AES256 , and sending the data over the network

I am trying to encrypt a NSString content and send it to the server.
AES keys, should not be a simple plain text.
Ex: "Password$5".
A salt should be added to it, so its like randomData + Password$5.
This key will be used for encrypting.
So, to the server I will be sending a JSON like this
{
password:"Encrypted Password with AES256"
}
Now, my question is the key is random because the salt is random, so how would i decrypt the AES256 received encrypted string?
Though I know the key (Password$5), but I don't know the salt?
Do I have to send the salt to the server(what would be the best place for it, should it be in the header or in the response itself), is it safe?
{
password: "Encrypted Password with AES256",
salt: "Random Hex bytes used"
}
Also, any way to handle this with Spring Restful services?
Just use https, all data and the query string are encrypted. Add certificate pinning and even MITM attacks are mitigated. Your encryption will be no better.
If you are determined to do your own encryption use RNCryptor. There is little chance that someone not steeped in cryptography will get the security right.
On the server do not save the password, run it through PBKDF2 with a salt and save the salt,iteration count and hashed password.
If your goal is to encrypt data being sent over the wire, you should handle this using a secure connection. This is between the servers, rather than handled by your application code.
If you the data itself should be encrypted, then you want to handle generation of salts, encryption on the server-side.
For passwords, you will want to hash them not encrypt them. There should never be a reason to de-crypt a password. You can always hash the provided password and compare hash values.

Secure Encryption of File on Disk

I want to be able to store some data on disk after being downloaded from a server that will be fairly resistant to hacking!
What I was going to do was encrypt the data with a private key on the server and decrypt it with the public key in the client, but the data is going to be arbitrary length and will be larger then a RSA private key.
My thinking was doing it this way would mean that if a hacker managed to decompile the code and get the encryption key they would be able to decrypt it but they wouldn't actually be able to modify the data as they would still need to the private key to encrypt it again after modification for the client to load!
So i thought of a combination of asymmetric encryption with symmetric encryption to store the data. So a symmetric encryption key would be asymmetrically encoded by the server and stored along side the symmetrically encrypted data then the client would decrypt the symmetric encryption key with its public key then decrypt the data!
But then I realised a hacker would just need to decompile the code, get the public key, decrypt the symmetric decryption key, decrypt the data, modify it then re-encrypt with the symmetric decryption key and he has hacked the system.
My question is does anyone have a suggestion in how I could go about storing this data on the client without it being hackable without knowing the private key! The data needs to be decrypt-able offline without any connection to a server required! So this rules out getting the data/keys from the server all the time!
There is no secure way to store data on the client. When data is on the client, a dedicated mind has all the tools and all the time in the universe to crack the best encryption that you can come up with.
There are two solutions:
Trust your client.
Stream the data.
Comments: If your client is also your enemy, then there is no way you can make business with them. The movie industry learned this, the music industry learned this, the book industry is learning it and the games industry is following. These people spent billions in clever DRM technologies and they all failed.
You want the customer's money? Then treat them accordingly.
Streaming is about the only workaround that balances trust and security. Streaming means that at any time, only a small fraction of the data is on the client at any time and combining the fragments into a whole data set is complex.

Change encryption key without exposing plaintext

We're designing a database system to store encrypted strings of information, with encryption and decryption performed client side using public-key cryptography.
If the key was ever changed though, this would necessitate reencrypting all the records client side, which is very impractical.
Is there any way this could be performed server side without exposing either the original (old) decryption key, or the message text?
I guess what I'm after is an associative cipher, something like this:
T( Eo(m) ) = En( Do(Eo(m) ))
where Eo(m) is the cipher text, Eo/Do the old pub/priv key pair, En the new pub key, m the message text and T the magical reencryption function.
Edit: T is calculated clientside and then sent to the server to be used.
You can't retroactively disable the old key anyway. Anyone who has access to the old data and the old key can decrypt the data no matter what you do.
I would suggest simply keeping a ring of keys. Add the new key to the ring and mark it active. Mark the old key expired. Code the client so that if it finds any data that's encrypted with an expired key, it re-encrypts it with the active key. (Or don't. What's needed depends on details of your implementation requirements.)
If desired, after a period of time, you can sweep for any data still encrypted with the old key and re-encrypt it.
You can't eliminate the exposure of the old key anyway, ever -- anyone who can find a backup or copy of data encrypted with the old key can decrypt it if they have the old key. Encryption keys must be protected forever or you get the fiasco that released the Wikileaks diplomatic cables to the public with the names of informants intact.
Think about your security perimeters. If you're worried about the server being compromised, consider building a harder-to-break subsystem which carried out the transcryption. You could do this with a non-network-attached server which was contacted only over a very tightly verified link protocol (over, say, a serial line), or a dedicated hardware security module. However, if you do something like this, you must think about how your keys are protected; if an attacker could steal the transient plaintext from your server, could they also steal the keys protecting it?

Resources