{"id":17831270,"url":"https://github.com/erikvw/django-crypto-fields","last_synced_at":"2025-09-08T09:37:02.503Z","repository":{"id":31019353,"uuid":"34577847","full_name":"erikvw/django-crypto-fields","owner":"erikvw","description":"Add encrypted field classes and more to your Django models.","archived":false,"fork":false,"pushed_at":"2025-08-12T04:18:07.000Z","size":850,"stargazers_count":29,"open_issues_count":4,"forks_count":8,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-09-07T20:21:41.678Z","etag":null,"topics":["django-crypto-fields","encrypted-fields","encryption"],"latest_commit_sha":null,"homepage":"https://django-crypto-fields.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erikvw.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-04-25T17:14:47.000Z","updated_at":"2025-09-06T18:56:36.000Z","dependencies_parsed_at":"2023-12-02T19:28:40.277Z","dependency_job_id":"426d070b-e050-454c-82ca-c4aebb65b77d","html_url":"https://github.com/erikvw/django-crypto-fields","commit_stats":{"total_commits":290,"total_committers":3,"mean_commits":96.66666666666667,"dds":0.006896551724137945,"last_synced_commit":"0f268e2889161cad538b4b8907b1130b8c9e14da"},"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/erikvw/django-crypto-fields","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvw%2Fdjango-crypto-fields","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvw%2Fdjango-crypto-fields/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvw%2Fdjango-crypto-fields/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvw%2Fdjango-crypto-fields/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erikvw","download_url":"https://codeload.github.com/erikvw/django-crypto-fields/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvw%2Fdjango-crypto-fields/sbom","scorecard":{"id":381281,"data":{"date":"2025-08-11","repo":{"name":"github.com/erikvw/django-crypto-fields","commit":"bfd680aefcec4bc83f92cff4c003eec19a74203c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":10,"reason":"21 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/erikvw/django-crypto-fields/build.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/erikvw/django-crypto-fields/build.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/erikvw/django-crypto-fields/build.yml/develop?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'develop'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 1 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T15:30:31.745Z","repository_id":31019353,"created_at":"2025-08-18T15:30:31.746Z","updated_at":"2025-08-18T15:30:31.746Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274121957,"owners_count":25225801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django-crypto-fields","encrypted-fields","encryption"],"created_at":"2024-10-27T19:42:50.640Z","updated_at":"2025-09-08T09:37:02.488Z","avatar_url":"https://github.com/erikvw.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"|pypi| |actions| |codecov| |downloads| |maintainability| |black|\n\ndjango-crypto-fields\n--------------------\nAdd encrypted field classes to your Django models where ``unique=True`` and ``unique_together`` attributes work as expected.\n\nCurrent version\n\n+-------------------------+----------------+---------------+----------+-----------+\n| Version                 | Python         | Django        | DB       | Cache     |\n+=========================+================+===============+==========+===========+\n| 1.0.0+                  | 3.12+          | 5.2+          | mysql    | cache     |\n|                         |                |               | postgres | framework |\n+-------------------------+----------------+---------------+----------+-----------+\n\nOlder versions\n\n+-------------------------+----------------+---------------+----------+-----------+\n| Version                 | Python         | Django        | DB       | Cache     |\n+=========================+================+===============+==========+===========+\n| \u003c 0.3.7                 | 3.8, 3.9, 3.10 | 3.2, 4.0, 4.1 | mysql    | N/A       |\n+-------------------------+----------------+---------------+----------+-----------+\n| 0.3.8 - 0.3.9           | 3.11+          | 4.2+          | mysql    | N/A       |\n+-------------------------+----------------+---------------+----------+-----------+\n| 0.4.0 - 0.4.1           | 3.11+          | 4.2+          | mysql    | cache     |\n|                         |                |               |          | framework |\n+-------------------------+----------------+---------------+----------+-----------+\n| 0.4.2+                  | 3.11+          | 4.2+          | mysql    | cache     |\n|                         |                |               | postgres | framework |\n+-------------------------+----------------+---------------+----------+-----------+\n\n\n\n``django-crypto-fields`` uses ``pycryptodomex``\n\nWe use this module in projects built with the `ClinicEDC`_: A clinical trials data management framework.\n\nUsage\n=====\n.. code-block:: python\n\n\n\tfrom django.db import models\n\tfrom django_crypto_fields.fields import EncryptedTextField, FirstnameField, IdentityField\n\n\tclass PatientModel (models.Model):\n\n\t    first_name = FirstnameField(\n\t        verbose_name=\"First Name\")\n\n\t    identity = IdentityField(\n\t        verbose_name=\"Identity\",\n\t        unique=True)\n\n\t    comment = EncryptedTextField(\n\t        max_length=500)\n\n\nInstallation\n============\n\nadd to INSTALLED_APPS:\n\n.. code-block:: python\n\n\tINSTALLED_APPS = (\n\t\t# ...\n\t    'django_crypto_fields.apps.AppConfig',\n\t    # ...\n\t)\n\nAdd DJANGO_CRYPTO_FIELDS_KEY_PATH to the folder in settings:\n\n.. code-block:: python\n\n    # folder where the encryption keys are stored\n    # Do not set for tests\n    DJANGO_CRYPTO_FIELDS_KEY_PATH = '/etc/myproject/django_crypto_fields'\n\nAdd KEY_PREFIX (optional, the default is \"user\"):\n\n.. code-block:: python\n\n\t# optional filename prefix for encryption keys files:\n\tKEY_PREFIX = 'bhp066'\n\n\nRun ``migrate`` to create the ``django_crypto_fields.crypt`` table:\n\n.. code-block:: bash\n\n    python manage.py migrate django_crypto_fields\n\n\nEncryption keys\n===============\n\nTake care of the encryption keys!\n\nIn your tests you can set ``settings.DEBUG = True`` and ``settings.AUTO_CREATE_KEYS = True`` so that keys are generated for your tests. Encryption keys will not automatically generate on a production system (``DEBUG=False``) unless ``settings.AUTO_CREATE_KEYS = True``.\n\nBy default assumes your test module is ``runtests.py``. You can changes this by setting ``settings.DJANGO_CRYPTO_FIELDS_TEST_MODULE``.\n\nWhen are encryption keys loaded?\n================================\n\nThe encryption keys are loaded as a side effect of accessing the ``keys`` module.\nThe keys module is imported in this apps AppConfig just before ``import_models``.\nDuring runtime the encryption keys are stored in the ``encryption_keys`` global.\n\nSee module ``apps.py``, module ``keys.py`` and ``fields.BaseField`` constructor.\n\nHistory\n=======\n\n``django-crypto-fields`` has been used in our audited research projects that use our \"Edc\" for data collection and management. Data collected in our Edc are considered \"source documents\". ``django-crypto-field`` adds field level encryption for sensitive field values such as names, identifiers, dob, etc (PII). Authorized study personnel accessing the data through the application can see PII. Downstream data management staff and statisticians accessing the database directly cannot.\n\nFeatures\n========\n\n* All values are stored as a pair of hash (``hashlib.pbkdf2_hmac``) and secret (``rsa`` or ``aes``);\n* A model using a ``django-crypto-fields`` field class stores the hash only;\n* A separate table relates the hash to it's secret and is referenced internally by the field class;\n\nAdvantages\n==========\n\n- Automatically creates encryption key sets (RSA, AES and salt) and stores them in the ``KEY_PATH`` folder;\n- Supports unique constraints and compound constraints that including encrypted fields. The hash is stored in the model's db_table and not the secret. The ``unique=True`` and ``unique_together`` attributes work as expected;\n- The dataset is de-identified at rest. This has many advantages but helps us work well with our analysis team. The data analysis team do not need to see PII. They just want a de-identified dataset. A de-identified dataset is one where PII fields are encrypted and others not. With the RSA keys removed, the dataset is effectively de-identified;\n- Datasets from other systems with shared PII values, such as identity numbers, can be prepared for meta-analysis using the same keys and algorithms;\n- The dataset can be permanently obscured by dropping the ``Crypt`` table from the DB (it has all the secrets);\n- By default field classes exist for two sets of keys. You can customize ``KEY_FILENAMES`` to create as many sets as needed. With multiple sets of keys you have more control over who gets to see what.\n\nDisadvantages\n=============\n\n- Limited support for lookup types. The \"query value\" is the hash not the decrypted secret, so Django lookups like ``['startswith', 'istartswith', 'endswith', 'iendswith', 'contains', 'icontains', 'iexact']`` are not supported.\n- Hashing with a secret may be considered less secure than just a \"secret\". You decide what your requirements are. For systems that collect PII in fields classes from ``django-crypto-fields``, we take all the basic security precautions: OS and application-level password protection, Full-Drive encryption, physical security and so on.\n\nOther encrypted field modules are available if you just want to use encrypted field classes in Django models and do not need unique constraints nor plan to join tables on encrypted fields for analysis.\n\nContribute\n==========\n\n- Issue Tracker: github.com/erikvw/django-crypto-fields/issues\n- Source Code: github.com/erikvw/django-crypto-fields\n\n.. _ClinicEDC: https://github.com/clinicedc\n\n.. |pypi| image:: https://img.shields.io/pypi/v/django-crypto-fields.svg\n    :target: https://pypi.python.org/pypi/django-crypto-fields\n\n.. |actions| image:: https://github.com/erikvw/django-crypto-fields/actions/workflows/build.yml/badge.svg\n  :target: https://github.com/erikvw/django-crypto-fields/actions/workflows/build.yml\n\n.. |codecov| image:: https://codecov.io/gh/erikvw/django-crypto-fields/branch/develop/graph/badge.svg\n  :target: https://codecov.io/gh/erikvw/django-crypto-fields\n\n.. |downloads| image:: https://pepy.tech/badge/django-crypto-fields\n   :target: https://pepy.tech/project/django-crypto-fields\n\n.. |maintainability| image:: https://api.codeclimate.com/v1/badges/34293a3ec19da8d7fb16/maintainability\n   :target: https://codeclimate.com/github/erikvw/django-crypto-fields/maintainability\n   :alt: Maintainability\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n   :target: https://github.com/ambv/black\n   :alt: Code Style\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvw%2Fdjango-crypto-fields","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferikvw%2Fdjango-crypto-fields","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvw%2Fdjango-crypto-fields/lists"}