{"id":17949520,"url":"https://github.com/kdawgwilk/blind_index","last_synced_at":"2025-04-03T15:42:06.166Z","repository":{"id":94411867,"uuid":"346639382","full_name":"kdawgwilk/blind_index","owner":"kdawgwilk","description":"Securely search encrypted database fields","archived":false,"fork":false,"pushed_at":"2021-03-11T09:23:12.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-09T04:26:37.331Z","etag":null,"topics":["ecto","ecto-extension","elixir","elixir-lang","privacy","security"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kdawgwilk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-11T09:00:55.000Z","updated_at":"2022-02-26T14:07:41.000Z","dependencies_parsed_at":"2023-04-23T02:28:57.137Z","dependency_job_id":null,"html_url":"https://github.com/kdawgwilk/blind_index","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdawgwilk%2Fblind_index","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdawgwilk%2Fblind_index/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdawgwilk%2Fblind_index/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdawgwilk%2Fblind_index/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kdawgwilk","download_url":"https://codeload.github.com/kdawgwilk/blind_index/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247030513,"owners_count":20872130,"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","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":["ecto","ecto-extension","elixir","elixir-lang","privacy","security"],"created_at":"2024-10-29T09:17:19.666Z","updated_at":"2025-04-03T15:42:06.145Z","avatar_url":"https://github.com/kdawgwilk.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blind Index\n\nSecurely search encrypted database fields. Inspired heavily by [ankane/blind_index](https://github.com/ankane/blind_index)\n\n[![Build Status](https://github.com/kdawgwilk/blind_index/workflows/build/badge.svg?branch=master)](https://github.com/kdawgwilk/blind_index/actions)\n\n## How It Works\n\nWe use [this approach](https://paragonie.com/blog/2017/05/building-searchable-encrypted-databases-with-php-and-sql) by Scott Arciszewski. To summarize, we compute a keyed hash of the sensitive data and store it in a column. To query, we apply the keyed hash function to the value we’re searching and then perform a database search. This results in performant queries for exact matches.\n\n## Leakage\n\nAn important consideration in searchable encryption is leakage, which is information an attacker can gain. Blind indexing leaks that rows have the same value. If you use this for a field like last name, an attacker can use frequency analysis to predict the values. In an active attack where an attacker can control the input values, they can learn which other values in the database match.\n\nHere’s a [great article](https://blog.cryptographyengineering.com/2019/02/11/attack-of-the-week-searchable-encryption-and-the-ever-expanding-leakage-function/) on leakage in searchable encryption. Blind indexing has the same leakage as [deterministic encryption](#alternatives).\n\n## Installation\n\nAdd `blind_index` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:blind_index, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\n## Prep\n\nTODO\n\n## Getting Started\n\nCreate a migration to add a column for the blind index\n\n```elixir\nadd :email_bidx, :string\nadd index :users, [:email_bidx]\n# unique_index if needed\n# add unique_index :users, [:email_bidx]\n```\n\nAdd to your model\n\n```elixir\ndefmodule User do\n  use Ecto.Schema\n  import BlindIndex, only: [blind_index: 1]\n\n  schema \"users\" do\n    blind_index :email\n  end\nend\n```\n\nFor more sensitive fields, use\n\n```elixir\ndefmodule User do\n  use Ecto.Schema\n  import BlindIndex, only: [blind_index: 2]\n\n  schema \"users\" do\n    blind_index :email, sensitive: true\n  end\nend\n```\n\nBackfill existing records\n\n```elixir\nBlindIndex.backfill(User)\n```\n\n## Key Separation\n\nThe master key is used to generate unique keys for each blind index. This technique comes from [CipherSweet](https://ciphersweet.paragonie.com/internals/key-hierarchy). The table name and blind index column name are both used in this process. If you need to rename a table with blind indexes, or a blind index column itself, get the key:\n\n```elixir\nBlindIndex.index_key(\"users\", \"email_bidx\")\n```\n\n## Key Generation\n\nGenerate a key with:\n\n```elixir\nBlindIndex.generate_key()\n```\n\nStore the key with your other secrets. This is typically an environment variable. Be sure to use different keys in development and production. Keys don’t need to be hex-encoded, but it’s often easier to store them this way.\n\nSet the following environment variable with your key (you can use this one in development)\n\n```sh\nBLIND_INDEX_MASTER_KEY=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n```\n\n## Alternatives\n\nOne alternative to blind indexing is to use a deterministic encryption scheme, like AES-SIV. In this approach, the encrypted data will be the same for matches. We recommend blind indexing over deterministic encryption because:\n\n1. You can keep encryption consistent for all fields (both searchable and non-searchable)\n2. Blind indexing supports expressions\n\n## History\n\nView the [changelog](https://github.com/kdawgwilk/blind_index/blob/master/CHANGELOG.md)\n\n## Contributing\n\nEveryone is encouraged to help improve this project. Here are a few ways you can help:\n\n- [Report bugs](https://github.com/kdawgwilk/blind_index/issues)\n- Fix bugs and [submit pull requests](https://github.com/kdawgwilk/blind_index/pulls)\n- Write, clarify, or fix documentation\n- Suggest or add new features\n\nTo get started with development and testing:\n\n```sh\ngit clone https://github.com/kdawgwilk/blind_index.git\ncd blind_index\nmix deps.get\nmix test\n```\n\nFor security issues, send an email to the address on [this page](https://github.com/kdawgwilk).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkdawgwilk%2Fblind_index","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkdawgwilk%2Fblind_index","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkdawgwilk%2Fblind_index/lists"}