Breaking up large data for RSA encryption - c

Recently we've been diving into using OpenSSL to help encrypt/decrypt some data we have. Each "client" will have Public/Private key pair and X509 Certificate given to them by a local Certificate Authority. I'm now looking into encrypting/decrypting data with that key pair.
Everything I've looked into show using the methods RSA_public_encrypt and RSA_private_decrypt for RSA encryption. But the amount of data I can encrypt at once is limited by RSA_size(rsa) - 41 for the padding type RSA_PKCS1_OAEP_PADDING. So my question is how to encrypt larger amounts of data while sticking to our RSA scheme (no static keyphrases, etc). I was thinking about breaking the data up into chunks and then encrypting it but that seems like it's defeating the point of padding.
Any help would be appreciated.

Even if you break the data, you will find out, that the speed is prohibitively slow. The right method is
Generate random key for symmetric algorithm
encrypt the data using symmetric algorithm and the random key
encrypt the random key using your public key and store it in the encrypted form next (or before) the data.

You should use a standard like CMS (the basis of the S/MIME support in your email client) or PGP. There are libraries for both of these standards for just about every platform.
You will find that they are very similar in their approach to bulk data encryption, using a symmetric cipher to encrypt data and encrypting that secret key with the public key of the "message" recipients. This approach is secure and fast.
However, these standards go further, securely handling things you might not have thought about yet, like encrypting the data for multiple recipients, attaching meta-data to the encrypted content, etc. You also get interoperability with other software. For example, if you use S/MIME, you can use just about any email client on any platform to decrypt. In fact, depending on your integration requirements, you might not need to write any software yourself.
Using one of these well-established protocols won't solve all of your security problems, but it will make it more difficult to do something really dumb.

Related

Using an HSM or Key vault service like Azure Key Vault

I'll start by saying I understand wanting to make data as safe as possible.
I have an app and I would like to just encrypt all of the information that can be used to personally identify someone in the database.
So I have read that it is terrible to store your key on the same server as the data. Okay so separate servers, no problem. Then I've read that It's terrible to put the key in the code on the app server (away from the data). People say that the proper way to store an encryption key is by using a HSM or a Key vault like Azure Key Vault. Ok, I am on-board with that but if my code has access to the HSM or the Azure Key Vault (which it would need to have in order to decrypt or access the data AT ALL...
If my code is stolen from the app server (which is why storing the key in the code itself would be insecure) Why couldn't an attacker just use the same method that my code uses to decrypt the data from the HSM or Key vault?
Assuming that it isn't safe to just store the key inside of the code itself.. How is it any different to have a method or a function that can decrypt the data in the code? That would essentially tell the attacker how to get the key from the vault anyway, wouldn't it?
What is the extra vector or layer that using an HSM or Keyvault prevents?
I don't mind paying for and implementing the extra layer. I am genuinely curious as I can't really see any difference.
I think your question is mainly about protecting secret keys in software vs. hardware key management solutions. the following links have useful information about their differences:
Usage of software/hardware-backed Android Keystore and possible security/usability drawbacks
https://www.itprotoday.com/iaaspaas/software-vs-hsm-protected-keys-azure-key-vault
if I understand your question correctly, it's because the application never sees the actual cryptographic keys. the HSM just exposes the primitive crypto operations, but never the keys themselves.
an attacker would therefore need to be logged into your "app server" in order to perform the operations, which is (hopefully) relatively easy to revoke/deny. if you had the keys available to the code itself then they could continue using the keys on any existing encrypted data until it has been re-encrypted after rotating in a new key. this also has associated assurance difficulties, e.g. how do you know the attacker didn't manipulate some data while this rotation was happening

How to keep track of encryption keys for individual files in a web service?

I'm working on adding the option to encrypt uploaded files on my website by giving each file a "password", but I'm not sure of the best way to keep track of the encryption keys for each individual file. For example, when retrieving the file if the user enters the wrong password I'm pretty sure it'll download the file, but it won't be unencrypted properly. Is it best to store the hashed & salted passwords for each file in a database and match up there first? Or is there a better way to do it?
If you store the encryption keys as hashed (and salted) values, there is no way to retrieve the original encryption key. If you hash something (with a strong hashing algorithm), you cannot get the original back.
The best mechanism depends on the operating environment (OS, plus potentially other software installed), and on the requirements.
Depending on the specific requirements, it may be best not to store the encryption key at all. The point is that the user wants to protect data and the user knows the key. If it is possible to perform the encryption on the client side, the key would never have to traverse the network at all (e.g. encrypt in JavaScript). If the encryption must happen on the server, ensure the key is sent via an https connection, use it in memory to encrypt the file, and remove from memory (if your language supports immediately removing something from memory... e.g. in C# use a SecureString).
If you must keep the encryption key (which is a security issue on several levels), you will have to state more information about the operating environment.

Encrypting a 4 digit password/pincode - easy to crack?

I am currently working on a service which requires users to pick a 4-digit password/pin, because it is a mobile service. I am encrypting those passwords with either 256 or 2048bit encryption and it will be hashed. The account is blocked after 4 wrong entries, and can only be entered by mobile phone. Would it be hard to crack those PINs? I am asking this because sensitive information is being stored. The database is connected to a web application, the application is loaded to the phone using twilio. The thing I am most scared for is that the database is being hacked via the web. What would be a good way to keep sensitive data secure?
If someone gets hold of the database, you would be pretty much screwed:
If you just encrypt the 4-digit passwords, an attacker can just build a table of the 10000 possible encrypted strings and can trivially decrypt the PINs.
If you use salt strings (and encrypt not PIN, but PIN+salt and store crypted(PIN+salt) alongside with salt), people have to make a per-password effort, but there are still only 10000 possibilities for each password (which is not very much).
Which means, yes, by all means you should keep the database off the web. (If the web application is only ever accessed through twilio, you can reject connections from any other IP range).
Since you're using twilio, just make sure that twilo only talks to your web service using a secure protocol and reject any requests that you aren't sure are coming from a trusted source (that is, twilo). No real need for a pin at all.
This is a huge webpage on how to setup ssl between your web server and twilo. It even has a php example.
http://www.twilio.com/docs/security
If you use PKCS#1 1.5 or 2.0 RSA encryption (view the standards) you will also encrypt a random padding. This means that in transit, the PIN's cannot be compared, as long as the padding is kept secret and is truly random (this is not a salt which should be made public).
As for the database, it would be a good idea to move it out of the normal operations as much as possible. Create a simple service that just checks the PIN after decryption, make sure you don't have buffer overruns etc. on that, and if possible, use a different machine and access rights than the production server. Really test this part well, as the interface is small, it should not be difficult.
If you and the phones are up to it, you might want to try ECC, but that's not for the meek. RSA encrypt normally uses a small public exponent (0x010001 is highly recommended) so it is faster than ECC for the phone. On the server (and during key creation) ECC is much faster. I would not recommend symmetric cryptography (AES/3DES) for this.
Oh, and include the public encryption key in the application (for implicit trust), don't send it over from the server. Keep the private key secret and inaccessible for anything other than the already mentioned service.
The interface you describe sounds secure to me. It's secure enough for ATMs!
Are the encrypted PINs easy to crack? Yes, there's only 10000 possible combinations and a rainbow table can be generated of all the possible encrypted values unless you salt. However that would require access to the encrypted PINs which means the attacker already has a copy of your database.
So really you need to ensure your database server is secure. There's a lot of variables that could make it insecure so it's a big question. Instead you could rely on third-party solutions like Amazon S3 or others and concentrate on coding instead of security. Let them do the hard work!
You should use good quality password salting technique to prevent against hacking passwords. Check the wikipedia article to know more about salting. Salt Article

Silverlight and Encryption, how to store/generate they key/iv pair?

I have a Silverlight app that connects to a php webservice. I want to encrypt the communication between the webservice and the Silverlight client. I'm not relying on SSL. I'm encrypting/decrypting the POST string myself using AES 256bit Key and IV.
The big questions then are:
How do I generate a random unique key/iv pair in PHP.
How do I share this key/iv pair between the web service and silverlight client in a secure way.
It seems impossible without having some kind of hard coded key or iv on the client. Which would compromise security.
This is a public website, there are no logins. Just the requirement of secure communication.
I can hard code the seed for the key/iv (which is hashed with SHA256 with a time stamp salt and then assigned as the key or iv) in PHP source code, that's on the server so that is pretty safe. However on the client the seed for the key/iv pair would be visible, if it is hard coded.
Further more using a time stamp as the basis for uniqueness/randomness is definitely not ok, since timestamps are predictable. It does however provide a common factor between the C# code and the PHP code.
The only other option that I can think of would be to have a 3rd service involved that provides the key/iv to the Silverlight client, as well as the php webservice. This of course start the cycle anew, with the question of how to store the credentials for accessing the key/iv distribution service on the Silverlight client.
Sounds like the solution is then asymmetric encryption, since sensitive data will be viewed only on the administrative back end of the website. Unfortunately Silverlight has no asymmetric encryption classes. The solution? Roll my own Diffie-Hellman key exchange! Plug that key into AES256!
The answers to your questions are: "SSL".
Symmetric encryption expands a shared secret of relatively small size (e.g. a 256-bit key) into a secure data transmission tunnel which ensures confidentiality and integrity. This is not as easy as it may seem; there are many small but deadly details.
Asymmetric cryptography is about establishing that shared secret over an insecure network. RSA encryption, Diffie-Hellman... are algorithms which can help you with that. You still have to begin somewhere; i.e., if you use the public key of the server (its RSA public key, its half of Diffie-Hellman...) then you must have some way to know that you are using the right public key, not the public key of some bad guy who intercepts the communication and feeds you his own key instead. There are ways to do that, mainly with hardcoding a public key within the client application, public key which is either the server public key or a key which can be used to sign it (that's certification). Of course, with Silverlight the client code is also downloaded, hence potentially tweaked by the same bad guy, so you would have to sign the code and have the browser verify that signature.
All this is hard work and has scores of pitfalls. The SSL protocol went through all of them, and was patiently but painfully updated and fixed. It took many years and many smart people, and there was much grinding of teeth. A similar protocol is SSH (some encoding details differ but the principles are the same). If you want to design your own protocol, then chances are that you will reenact most of the weaknesses and issues that plagued SSL and SSH. Simply using SSL or SSH would save you much time and trouble.
You could use a public/private key encryption system like RSA. The client would encrypt a packet using the well-known public key of the server, send the encrypted data, and the server would decrypt it using the secret private key. Anyone can send the server data encrypted using the public key, but only the server can decrypt it. Just like SSL does.
Which brings us back to the question: why aren't you using SSL?

What's the best way to keep decryption key for decrypting encrypted database?

I have a encryted database and decryption key. How to keep decryption key away from hacking(Both database hacking and unauthorizated accessing PC.)?
Hardcode in assembly.
keep in registry.
keep in RAM.
Moreover, I need algorithm for encryted data. What's the best algorith for doing this in security per decryption time term?
RSA
AES
Twofish
RSA vs AES
Thanks,
You are asking the wrong questions: first you need to decide how secure you need things to be. Then you need to decide whether you want symmetric (think DES, shared key)) or asymmetric (think RSA, public and private keys), and also think hard about key management, because that is often the point of weakness.
Asymmetric algorithms are orders of magnitude slower than symmetric ones; they are often used to protect a symmetric key, rather than on the whole data.
There is no way to "keep the decryption key away from hacking" if you store it with the encrypted data. Period. Key management is often the hardest part of any security policy.
As for encryption algorithm, RSA is a very different type of algorithm to AES and twofish (see http://en.wikipedia.org/wiki/Symmetric-key_algorithm#Symmetric_vs._asymmetric_algorithms).
To answer both questions will require more information. Exactly why are you trying to encrypt the database? What threat are you trying to manage?
It will never be perfectly secure, especially given physical access to the machines, but you can make it difficult.
Use 3DES to encrypt the database fields you want to protect. Note that you will not need to encrypt every field, and you shouldn't. (both for speed, and because if you lose the key, you'll at least have a clue what you need to do)
Do not store the key on the database server. If you must, store it on a different drive than the database or web app.
Keep a backup of the key on a thumb drive or something. Do not skip this step.
Split the keyfile into several different files, scattered over different folders and different drives. Do not use names that indicate the purpose of the files. Store the locations in the registry.
Use code to read the registry, fetch the pieces of the key, and assemble them. Write this code yourself, and do not use a name that indicates the program's purpose.
I interpret your description that it is necessary to hold the decryption key SOMEWHERE on the database machine to carry out your work.
Given sufficient knowhow and access to the hardware you cannot protect your database that it is impossible to break through your encryption.
For all other cases where physical access is not possible you should refer to the encryption guidelines which exist for all major databases using the specific technologies unique to most platforms.

Resources