django-cryptography icon indicating copy to clipboard operation
django-cryptography copied to clipboard

Add support for PyCryptodome

Open georgemarshall opened this issue 5 years ago • 5 comments

Add PyCryptodome as an alternative to Cryptography. Additionally consider making PyCryptodome the default implementation.

Advantages:

  • Doesn't use OpenSSL
  • No FFI binding like Cryptography
  • More cryptographic algorithms including elliptic curve variants.

Disadvantages:

  • Not as many followers (less eyes on code for auditing)

georgemarshall avatar Nov 09 '19 18:11 georgemarshall

Hi @georgemarshall , personally I need a similar implementation as this project, but using an Azure Key Vault as the cryptography backend. I was planning on either taking inspiration form your project, but then realised the solution might be to create support for any "Cryptography Backends", similar to how in django you can already use various "Authentication Backends" or "Database Backends".

The idea would be to define a standard for a Cryptography Backend that can support a few standard methods: encrypt(message), decrypt(message), calculate_encrypted_max_length() etc. All would be defined by a few settings in the django settings.py.

In my case, I will use the Azure Key Vault API to encrypt and decrypt values remotely, so I won't even have to manage any key locally etc. , nor install any cryptography dependency.

Anyway: do you know if there already exists such a "Cryptography Backend" standard concept in django? Do you think it would be a good idea to create one?

I'll be trying a version of this on my side in any case.

Bastien-Brd avatar Nov 13 '19 11:11 Bastien-Brd

I do realise there is this concept of backends already within the python Cryptography module, but I was thinking of a higher level one, to choose between local python crypto module (with extra settings defining the crypto backend within cryptography module, confusing) or another cryptography provider such as a remote REST API for example (the Azure Key Vault API in my case, which allows to encrypt/decrypt messages over REST calls).

Bastien-Brd avatar Nov 13 '19 16:11 Bastien-Brd

My initial understanding is that you are trying to leverage a service such as Azure Key Vault or AWS Secrets Manager to store the sensitive data. Which would create an entry for every item that would be inserted into the database.

There are two items to address here. Firstly they do not replace the functionality that django-cryptography provides, they just augment the configuration of it. Second the vault services are not capable of storing the same amount of data as a BinaryField within Django.

Ideally I could see a configuration helper that would pull encryption keys from the vault and populate them inside the Django settings.py file. This would work similar to populating settings from environment variables to set the SECRET_KEY and CRYPTOGRAPHY_KEY. The idea of the vault services is create zero knowledge encryption keys and automatic distribution of them to approved applications.

georgemarshall avatar Nov 13 '19 21:11 georgemarshall

Thanks for getting back to me.

Actually that is not what I meant. The Key Vault is just a secure vault that holds on to the encryption key, and provides a REST API so that the application can either:

  • read the key remotely (and provision it in a django secret setting for example as you point out) but that is not ideal (I don't want the key to leave the vault at all, in fact I don't the application to be able to read the key even
  • or actually just send a message to the vault for encryption (via a JSON payload in a POST request, with options on which algo to use etc.), let the vault do the encryption operation using the key it stores, and respond with the encrypted message as JSON again

So really the vault is the cryptography backend only. My django app then just saves that encrypted value in the app database. Similarly upon reading an encrypted field from database, the application makes another request to the vault API POSTing the encrypted value and asking for decryption, receives the decrypted value in response.

I would define a class in my application, something called AzureKeyVaultCrypter that implements a few methods AzureKeyVaultCrypter.encrypt(value) and AzureKeyVaultCrypter.decrypt(value) (these methods make API requests to the remote vault for these operations), and in your code, I would just replace the encrypt() and decrypt() methods to use my own crypter instead of python cryptography. The rest is the same.

Bastien-Brd avatar Nov 14 '19 10:11 Bastien-Brd

I like the idea of being able to slot-in a different encryption backend as @Bastien-Brd has suggested.

I also think that adopting a single new backend makes a lot of sense. Eliminating the libffi dependency will make this board a lot quieter!

thismatters avatar Apr 12 '21 20:04 thismatters