reidmorrison / symmetric-encryption

Symmetric Encryption for Ruby Projects using OpenSSL
https://logger.rocketjob.github.io/
Apache License 2.0
475 stars 92 forks source link

Multiple ciphers #60

Open michaelirey opened 8 years ago

michaelirey commented 8 years ago

I apologize in advance being this may not be a feature of symmetric-encryption. But I was unsure of where else I could ask.

Our app has a need to encrypt data for different purposes and control access for decrypting. Some data should use one cipher while other data should use another cipher.

It looks like you can configure secondary ciphers, but it looks like this more for key rotation.

What is your suggestion? Use secondary ciphers, multiple symmetric-encryption instances each with their own config (I don't know if this is even possible), or some other method I am not clearly seeing?

Thanks!

reidmorrison commented 8 years ago

The simplest way is to add the multiple ciphers to the symmetric-encryption.yml configuration file, each with a unique version number.

Then to encrypt data with the version 3 key:

encrypted = SymmetricEncryption.cipher(3).encrypt("Hello World")
# "QEVuQwIAPiplaSyln4bywEKXYKDOqQ=="

If headers are enabled in the config file, then the usual SymmetricEncryption.decrypt will decrypt any encrypted value since the header will indicate which cipher was used for encryption purposes.

SymmetricEncryption.decrypt(encrypted)
# "Hello World"

It is also possible to store customer/client specific ciphers in a database table ( or other data source ), protected using the global cipher. This is a more powerful, yet more complex approach that requires creating an managing instances of SymmetricEncryption::Cipher. Let me know if you need more information on this approach.

dpneumo commented 7 years ago

Customer/client specific ciphers is precisely what I have been contemplating but it has not been clear to me how to apply a stored cipher to a specific customer's records. From what you said above I can imagine that I should be able to use the customer_id as the key version (or perhaps use customer_id as index into a table containing the key version and cipher.) Does that seem appropriate? BTW. Do the key version numbers have to be sequential? A random key version number would add an additional layer of complexity for a hacker.

kennethteh90 commented 3 years ago

The simplest way is to add the multiple ciphers to the symmetric-encryption.yml configuration file, each with a unique version number.

Then to encrypt data with the version 3 key:

encrypted = SymmetricEncryption.cipher(3).encrypt("Hello World")
# "QEVuQwIAPiplaSyln4bywEKXYKDOqQ=="

If headers are enabled in the config file, then the usual SymmetricEncryption.decrypt will decrypt any encrypted value since the header will indicate which cipher was used for encryption purposes.

SymmetricEncryption.decrypt(encrypted)
# "Hello World"

It is also possible to store customer/client specific ciphers in a database table ( or other data source ), protected using the global cipher. This is a more powerful, yet more complex approach that requires creating an managing instances of SymmetricEncryption::Cipher. Let me know if you need more information on this approach.

Hi @reidmorrison, I saw that you mentioned storing client-specific ciphers in a db table... what would be the best way for me to find out more about this approach?