{"id":13507688,"url":"https://github.com/ntrepid8/ex_crypto","last_synced_at":"2025-10-21T14:57:14.671Z","repository":{"id":2390392,"uuid":"44831591","full_name":"ntrepid8/ex_crypto","owner":"ntrepid8","description":"Wrapper around the Erlang crypto module for Elixir.","archived":false,"fork":false,"pushed_at":"2024-06-26T10:13:12.000Z","size":192,"stargazers_count":155,"open_issues_count":11,"forks_count":51,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-21T14:57:10.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ntrepid8.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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":"2015-10-23T18:39:31.000Z","updated_at":"2025-10-11T04:49:53.000Z","dependencies_parsed_at":"2024-06-18T15:37:02.868Z","dependency_job_id":"ba815fbd-3bfb-47a5-a300-e59623daba23","html_url":"https://github.com/ntrepid8/ex_crypto","commit_stats":{"total_commits":97,"total_committers":14,"mean_commits":6.928571428571429,"dds":"0.20618556701030932","last_synced_commit":"0997a1aaebe701523c0a9b71d4acec4a1819354e"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ntrepid8/ex_crypto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntrepid8%2Fex_crypto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntrepid8%2Fex_crypto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntrepid8%2Fex_crypto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntrepid8%2Fex_crypto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ntrepid8","download_url":"https://codeload.github.com/ntrepid8/ex_crypto/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntrepid8%2Fex_crypto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280281400,"owners_count":26303709,"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-10-21T02:00:06.614Z","response_time":58,"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":[],"created_at":"2024-08-01T02:00:37.820Z","updated_at":"2025-10-21T14:57:14.655Z","avatar_url":"https://github.com/ntrepid8.png","language":"Elixir","funding_links":[],"categories":["Cryptography","Frameworks and Libs"],"sub_categories":["Elixir"],"readme":"# ExCrypto\n\n[![Build Status](https://travis-ci.org/ntrepid8/ex_crypto.svg?branch=master)](https://travis-ci.org/ntrepid8/ex_crypto)\n[![Module Version](https://img.shields.io/hexpm/v/ex_crypto.svg)](https://hex.pm/packages/ex_crypto)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/ex_crypto/)\n[![Total Download](https://img.shields.io/hexpm/dt/ex_crypto.svg)](https://hex.pm/packages/ex_crypto)\n[![License](https://img.shields.io/hexpm/l/ex_crypto.svg)](https://github.com/ntrepid8/ex_crypto/blob/master/LICENSE.md)\n[![Last Updated](https://img.shields.io/github/last-commit/ntrepid8/ex_crypto.svg)](https://github.com/ntrepid8/ex_crypto/commits/master)\n\nThe goal of `ExCrypto` and `ExPublicKey` is to expose a subset of the functionality from the Erlang modules `crypto` and `public_key` so that writing secure Elixir applications is a little bit easier without being overwhelming. In many functions some sane defaults are provided to decrease the complexity of implementing those functions in your own code.\n\n## Using ExPublicKey\n\nThe `ExPublicKey` module provides functions for working with RSA public/private key operations. There are a couple common uses for public-key cryptography:\n\n- [Authenticate a message](#authenticate-a-message)\n- [Transmit a shared secret](#transmit-a-shared-secret) (session key)\n\n### Authenticate a message\n\nThe goal of `ExPublicKey.sign` and `ExPublicKey.verify` is that the recipient of a message can identify the sender. This can be accomplished as follows:\n\n*Note: assume the message is a JSON payload.*\n\n- Sender\n  - serialize the JSON to a string\n  - hash, time-stamp, and sign with your private-key\n- Receiver\n  - ensure the time-stamp is within the current window\n  - verify the signature with the sender's public-key\n\nHere are the steps in order:\n\n```elixir\n# load the RSA keys from a file on disk\nrsa_priv_key = ExPublicKey.load!(\"/path/to/private_key.pem\")\nrsa_pub_key = ExPublicKey.load!(\"/path/to/public_key.pem\")\n\n# create the message JSON\nmsg = %{\"name_first\"=\u003e\"Chuck\",\"name_last\"=\u003e\"Norris\"}\n\n# serialize the JSON\nmsg_serialized = Poison.encode!(msg)\n\n# generate time-stamp\nts = DateTime.utc_now |\u003e DateTime.to_unix\n\n# add a time-stamp\nts_msg_serialized = \"#{ts}|#{msg_serialized}\"\n\n# generate a secure hash using SHA256 and sign the message with the private key\n{:ok, signature} = ExPublicKey.sign(ts_msg_serialized, rsa_priv_key)\n\n# combine payload\npayload = \"#{ts}|#{msg_serialized}|#{Base.url_encode64 signature}\"\nIO.puts payload\n\n# pretend transmit the message...\n# pretend receive the message...\n\n# break up the payload\nparts = String.split(payload, \"|\")\nrecv_ts = Enum.fetch!(parts, 0)\nrecv_msg_serialized = Enum.fetch!(parts, 1)\n{:ok, recv_sig} = Enum.fetch!(parts, 2) |\u003e Base.url_decode64\n\n# pretend ensure the time-stamp is not too old (or from the future)...\n# it should probably no more than 5 minutes old, and no more than 15 minutes in the future\n\n# verify the signature\n{:ok, sig_valid} = ExPublicKey.verify(\"#{recv_ts}|#{recv_msg_serialized}\", recv_sig, rsa_pub_key)\nassert(sig_valid)\n\n# un-serialize the JSON\nrecv_msg_unserialized = Poison.Parser.parse!(recv_msg_serialized)\nassert(msg == recv_msg_unserialized)\n```\n*Note: this example is similar to the test \"sign and verify a JSON payload\" in `test/ex_public_key_test.exs`.*\n\n### Transmit a shared secret\n\n*(in progress)*\n\n### Load the keys from PEM format files\n\nFirst load the public/private RSA keys from disk:\n\n```elixir\niex(1)\u003e {:ok, rsa_private_key} = ExPublicKey.load(\"/tmp/test_rsa_private_key.pem\")\n{:ok, %ExPublicKey.RSAPrivateKey{...}}\n\niex(2)\u003e {:ok, rsa_public_key} = ExPublicKey.load(\"/tmp/test_rsa_public_key.pem\")\n{:ok, %ExPublicKey.RSAPublicKey{...}}\n```\n\n### Sign with RSA private key\n\nTo create a signature with the `RSAPrivateKey` like this:\n\n```elixir\niex(3)\u003e message = \"A very important message.\"\n\"A very important message.\"\n\nex(4)\u003e {:ok, signature} = ExPublicKey.sign(message, rsa_private_key)\n{:ok, \u003c\u003c...\u003e\u003e}\n```\n\n### Verify signature with RSA public key\n\n```elixir\niex(5)\u003e {:ok, valid} = ExPublicKey.verify(message, signature, rsa_public_key)\n{:ok, true}\n```\n\n### Encrypt with RSA public key\n\n```elixir\niex(6)\u003e clear_text = \"A super important message\"\n\"A super important message\"\niex(7)\u003e {:ok, cipher_text} = ExPublicKey.encrypt_public(clear_text, rsa_public_key)\n{:ok, \"Lmbv...HQ==\"}\n```\n\n### Decrypt with RSA private key\n\n```elixir\niex(8)\u003e {:ok, decrypted_clear_text} = ExPublicKey.decrypt_private(cipher_text, rsa_private_key)\n{:ok, \"A super important message\"}\n```\n\n## Using ExCrypto\n\nThe `ExCrypto` module provides relatively functions for AES cryptography operations.\n\n### Generate AES keys\n\nGenerate a new 128 bit AES key like this:\n\n```elixir\niex(1)\u003e {:ok, aes_128_key} = ExCrypto.generate_aes_key(:aes_128, :bytes)\n{:ok, \u003c\u003c...\u003e\u003e}\n```\n\nOften it's more convenient to handle the key as a base64 encoded string and you can generate a new key, already encoded as a base64 Unicode string like this:\n\n```elixir\niex(2)\u003e {:ok, aes_128_key} = ExCrypto.generate_aes_key(:aes_128, :base64)\n{:ok,\n \"deGqaW9gP1_0WlSomf2pZDzeyGcitSmfXYu7ygTsypsrSmvTVfl7ANQsTWc30TP9IftiBnmDlqkuU1ARzAN82Fo1NMJhvVi3iWkzYe9yusm0s3ymUh4Hs2O7oZCgJeavFwuHgrpk_79nyfe3HkSNoAVjNWv0ImOmLyClrPIa3qk=\"}\n ```\n\n You can also generate 192/256 bit AES keys like this:\n\n ```elixir\n iex(3)\u003e {:ok, aes_192_key} = ExCrypto.generate_aes_key(:aes_192, :base64)\n{:ok,\n \"P173Su55_bFR4WEf4SmKC4yKAX-IT9-83rbS6RSIPxEHf7uTEvyr969C3ZCkbSh5dJrWd35zjYQM-l5DpGzdIztxCqvN9myGYUdrfn9D2PRh9Y7XgQWRqYJ6FE67EHcNgJWrxEQ_HRt5jBczoY-34AZAN3RVcVqXrwGZw6ISJcyKVc30nJOBS9N4QeQWw2bPrppfzA43-_hAVfjEKCUyPzi2zlG2WUsaeKS4vOOmVAzkC0IPbONqVtzlxiFwbr7I\"}\n\niex(4)\u003e {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :base64)\n{:ok,\n \"Bs_BzhuwseEA8ZUvuEY0mq9Rmlv6cSoU_RaYD14Q62HiN_kJ4FiaW0YYppf1ffYPQ56xuitxQtYAnaeP-Q5l1WPh5aExdwCG_PUm5g-MlOUA1XSSP2RvuQqAiHzazIzjGVSIcl0Gr7TSLPOoIQrPshMNaA4j3SGZ3lAOqO1quvXtDn-9Sxwr5dwV7VzOIvXRwb0GbZeYp8lnVJgeqHl8cEhUTfT_h9Pm7tU2CFeHZCDK8ntFT_t4q6VlcBcvw_Pj3CGcVSmpmCHMKW1brt6jXGBijqSTdbjYDZnCx2Q44VoYqMMZ1U2GnVyjc-ZuwugwGGqQ7UEqV_TOMjbK6Oxx-Q==\"}\n ```\n\n In both examples the `:bytes` atom can be substituted for `:base64` if you wish to receive your key as a `bitstring` rather than as a base64 encoded Unicode string.\n\n As you can see the keys grow longer in order of bit length.  A 128 bit key is more than sufficient for most applications but if you are slightly more paranoid than average use a 192 bit key.\n\n If your paranoia knows no bounds or you are protecting state secrets from nation-state owned quantum computers use a 256 bit key.\n\n If you are concerned about hyper-advanced aliens with quantum computers you might need a longer key. Enterprise grade keys such as this can be generated upon request in the context of a consulting agreement.  For this application we recommend at least a 612 bit key.\n\n## Copyright and License\n\nCopyright (c) 2015 Josh Austin\n\nThis work is free. You can redistribute it and/or modify it under the\nterms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntrepid8%2Fex_crypto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fntrepid8%2Fex_crypto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntrepid8%2Fex_crypto/lists"}