I am working on encryption and I am currently using an openssl_encrypt
solution to encrypt my data. Currently I am rewriting an old codebase that uses openssl_public_encrypt
and openssl_private_decrypt
.
Of course I will have to match the encryption that was used previously, but I am thinking about undoing the encrypted data and rewriting the encryption and decryption methods for it.
The downside with openssl_public_encrypt
values, is that they can not be larger than the certificate that is used for encryption. This downside does not exist for openssl_encrypt
.
http://php.net/manual/en/function.openssl-public-encrypt.php#55901
The workaround in the legacy code base was to glue encrypts pieces together to be able to encrypt large data. This seems pretty messy and intensive to me.
My current solution is using openssl_encrypt
with a simple generated key like Laravel would generate a key for it:
protected function generateRandomKey()
{
return 'base64:'.base64_encode(random_bytes(
$this->laravel['config']['app.cipher'] == 'AES-128-CBC' ? 16 : 32
));
}
This works brilliantly but with the old code base have chosen SSL certificates for encrypting/decrypting for a reason that I am yet not fully aware of.
What would be the advantage/disadvantage with openssl_encrypt
vs the public/private way?
I guess working with third parties you can provide them your public certificate, but you could just as well provide them your generated key.
If third parties(like a financial system) need access to encrypted they can decrypt it just as well.
In both cases you are supplying the key to decrypt your data.
I am hoping somebody can shed some light on why you would limit yourself to encrypt values no longer than your certificate so you could use the public/private openssl
functions.
Cheers.
some light... ok...
first let's look at what algorithms or categories of algorithms we are dealing with here:
public/private key ... this means asymetric cryptography with algorithms like RSA... DH ...
in contrast to symetric cryptography with algorithms like AES ... DES ... TwoFish...
if your codebase contains stuff like gluing together chunks of encrypted data because the datasize was too large for the asymetric algorithm, one can safely say whoever build that did not know what he/she was doing.
symetric algorithms are used to encrypt bulk data ... asymetric algorithms are used to encrypt the symetric key so that the owners of the corresponding private keys can decrypt the symetric key and therefore can decrypt the bulk data ciphertext
the key for a symetric cipher like AES is not larger that the size restriction you find in the described methods
the reason for asymetric cryptography is that you can share your public key with the world, and everyone can encrypt data for you (data here means in 99% of all real world scenarios: symetric keys) but only you as the holder of the private key can decrypt ... the private key never leaves your hands ... noone ever has access to that except the owner
a certificate is merely a public key + metadata
that metadata contains information about who owns the keypair, what it may be used for, from when to when the keypair is valid, etc...
the metadata is put into a specific format and signed by a trusted third party ... the result is what you call a certificate
the signature on the certificate is something else you can do with public key crypto ... but this time the other way around ... to create the signature for a certain set of data, you need the private key... without it you can't sign ... but everyone that holds the public key can verify the signature ... if you change a single bit in the data the signature belongs to, it becomes invalid, so you cannot simply tamper with the contents of a certificate and for example change the key
update:
if you need some thirdparty to be able to send you encrypted data while they have your public key:
-they create a RANDOM symetric key that will be only known to them (let's call it Ksym)
-they encrypt whatever data they need with that key and a symetric cipher ... (ct=ENC(DATA,Ksym))
-they encrypt Ks for you using your public key (eKsym=ENC(Ksym,Kpub))
-they send you ct and eKsym
-you decipher eKsym (Ksym=DEC(eKsym,Kpriv))
-you decipher DATA = DEC(ct,Ksym)
facts:
only you and that third party know Ksym
if you want to store that data in a way even that thirdparty can not decrypt, you need to renecrypt it
if you store eKsym and ct only you and the thirdparty that originally encrypted the data have knowledge of the needed decryption key Ksym (and of course everyone who got the key from either you or said third party)
the fun fact is: Ksym is different for every piece of incoming data and is only valid for that piece of data ... sharing one Ksym with another third party only gives access to the one pice of data that belongs to this key
If you are unsure how to solve this problem then you should back away now and hire someone that knows what they are doing to solve it. Not being mean or rude, it's just better to do it right. Whoever worked on this before you obviously had no idea what they were doing, don't add yourself to that list.
If you were going to solve this problem yourself (which I don't think you should), I would recommend you use TLS to secure your connection between you and your end users, receive whatever data they are sending you, and then encrypt that and store it. I don't really know why you (or whoever worked on this before you) thought it would be beneficial to encrypt data at rest with the keys on the same device... A lot of work for practically no security.