{"id":15713770,"url":"https://github.com/tlrasor/incremental_hmac","last_synced_at":"2025-10-27T15:38:21.458Z","repository":{"id":146824839,"uuid":"213455928","full_name":"tlrasor/incremental_hmac","owner":"tlrasor","description":"Incremental HMAC API for Crystal","archived":false,"fork":false,"pushed_at":"2019-10-07T20:40:30.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-05T21:58:17.417Z","etag":null,"topics":["crystal","crystal-lang","crystal-language","crystal-shards","hmac","standard-library","utility-library"],"latest_commit_sha":null,"homepage":null,"language":"Crystal","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/tlrasor.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-07T18:22:43.000Z","updated_at":"2019-10-07T21:38:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"33795c5a-fa39-466f-a0f3-2791be72b698","html_url":"https://github.com/tlrasor/incremental_hmac","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/tlrasor%2Fincremental_hmac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlrasor%2Fincremental_hmac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlrasor%2Fincremental_hmac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlrasor%2Fincremental_hmac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tlrasor","download_url":"https://codeload.github.com/tlrasor/incremental_hmac/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246366642,"owners_count":20765738,"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":["crystal","crystal-lang","crystal-language","crystal-shards","hmac","standard-library","utility-library"],"created_at":"2024-10-03T21:33:23.319Z","updated_at":"2025-10-27T15:38:21.404Z","avatar_url":"https://github.com/tlrasor.png","language":"Crystal","funding_links":[],"categories":[],"sub_categories":[],"readme":"# incremental_hmac\n\n[![Build Status](https://travis-ci.org/tlrasor/incremental_hmac.svg?branch=master)](https://travis-ci.org/tlrasor/incremental_hmac)\n\nThe standard library's HMAC implementation is rather limited in that it can only work on data that has a `to_slice` method defined. This works fine for the typical web use cases for strings and byte buffers but does not scale well to calculating the HMAC of large files which are inconvenient to fit in memory.\n\nThis shard monkey patches OpenSSL::HMAC and adds an incremental interface modeled on Ruby's OpenSSL::HMAC class. It does this by calling into the same LibCrypto wrapper that the standard library does and should be \"fairly safe\" but I wouldn't advise it for production use at this time.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n   ```yaml\n   dependencies:\n     incremental_hmac:\n       github: tlrasor/incremental_hmac\n   ```\n\n2. Run `shards install`\n\n## Usage\n\n```crystal\nrequire \"incremental_hmac\"\n## The incremental interface is an instance of HMAC\nhmac = OpenSSL::HMAC.new(algorithm, key)\n# get an IO/something that produces slices\nFile.open(path, \"r\") do |io|\n  data_slice = Bytes.new(8192)\n  loop do\n    read = io.read(data_slice)\n    break if read \u003c 1\n    ## Here we update the hmac with the current buffer\n    hmac \u003c\u003c data_slice[0, read]\n  end\nend\n## Now just call digest or hexdigest to finalize\nhmac.digest\n```\nNote, currently, HMAC digests can currently only be called once because the structure is finalized. This is somewhat a consequence of the backing C library and some thought needs to be put into how to solve this.\n\n### Helpers\n\nThere are also some class method helpers which can handle reading the data in from a file\n\n```crystal\nkey = \"\u003csome secret hmac key\u003e\"\npath = Path[\"\u003csome file path string\u003e\"]\ndigest = OpenSSL::HMAC.hexdigest(OpenSSL::Algorithm::SHA256, key, path)\n```\n\n## Development\n\nDo some dev and write some tests plz\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/tlrasor/incremental_hmac/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Travis Rasor](https://github.com/tlrasor) - creator and maintainer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlrasor%2Fincremental_hmac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlrasor%2Fincremental_hmac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlrasor%2Fincremental_hmac/lists"}