{"id":14955945,"url":"https://github.com/technion/messagesodium","last_synced_at":"2025-10-24T09:30:24.822Z","repository":{"id":56883389,"uuid":"102188142","full_name":"technion/messagesodium","owner":"technion","description":"Patches ActiveSupport's MessageEncryptor to use libsodium","archived":false,"fork":false,"pushed_at":"2017-09-12T22:44:31.000Z","size":29,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-29T14:18:07.235Z","etag":null,"topics":["encryption","rails"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/technion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-02T10:06:08.000Z","updated_at":"2019-11-28T23:46:20.000Z","dependencies_parsed_at":"2022-08-20T22:31:09.673Z","dependency_job_id":null,"html_url":"https://github.com/technion/messagesodium","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technion%2Fmessagesodium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technion%2Fmessagesodium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technion%2Fmessagesodium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technion%2Fmessagesodium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/technion","download_url":"https://codeload.github.com/technion/messagesodium/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237944039,"owners_count":19391588,"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":["encryption","rails"],"created_at":"2024-09-24T13:12:03.766Z","updated_at":"2025-10-24T09:30:24.493Z","avatar_url":"https://github.com/technion.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Messagesodium\n\nProject status: Stable\n\nPatches Cookiestore to use libsodium for encryption and verification.\n[![Build Status](https://travis-ci.org/technion/messagesodium.svg?branch=master)](https://travis-ci.org/technion/messagesodium)\n\n# Cookistore\n\nRails [Cookiestore](https://www.justinweiss.com/articles/how-rails-sessions-work/) is a heavily underrated feature. It bought commonsense to session management at a time when [saving every user session in its own tmpfile on a server](http://php.net/manual/en/function.session-start.php) was slow and unreasonable to scale. And finally it avoided by default the horrible security issues we've seen with directly storing session variables in a cookie.\n\nThis gem brings an alternative backend to CookieStore.\n\n## Reason\n\nThere are a series of benefits described below. None of these are highly compelling on their own, but I recommend considering the way these features add up.\n\n# Use\n\nJust insert this gem into your Gemfile like any other:\n\n    gem 'messagesodium'\n\nAnd run your usual bundle installation. Any existing sessions will be invalidated, much like if you changed your secret key.\nYou can test it is active by looking at any session cookie. The absence of the \"--\" delimiter will confirm you are using this gem.\n\n# Demonstration\n\n[This gist](https://gist.github.com/technion/5cb2c6fbc570f6c1bc66e30bfb072cdf) shows a few interesting benchmarks, which we can refer to when describing what this gem offers.\n\n```\n\nCookiestore data is: SWFQbTg0dCtheE45TXU0dWRtT25ndjJVSEdWTE8vei9LMVpZYWVjaWZjaFppdUk5aklVRWZEUy9TOUJuMFpYd2dDMndVZkt0eTR5Sm04Y1FjQzk0M00wRnhTRERHdDhnT3c1dTBvTnRad009LS16WlFaeE82dy84VzA4NThYQzk5bTVBPT0=--efcb8809421d2dc1665c9d9afa9638c1c2a763eb\nwhich is 222 in length\nSodium data is: SGwQn0DD+pOvTPo68nvNYQLRFMt+Mf7rFU6BkiKhA0qHGT8BHVuqXRqEOYy+xcOoMCCRh99eeb/sVWlPzA4/FavTyg4U0PUAns0bx/Q9j4gcoD6K/h0z8yZvW0425g==\nwhich is 128 in length\n                                       user     system      total        real\nto_json                            2.470000   0.000000   2.470000 (  2.514048)\nJSON.dump                          0.520000   0.000000   0.520000 (  0.534084)\ncookiestore encrypt and sign       1.810000   0.030000   1.840000 (  1.915375)\ncookiestore decrypt and verify     2.730000   0.000000   2.730000 (  2.824819)\nlibsodium encrypt and sign         1.580000   0.060000   1.640000 (  1.738750)\nlibsodium decrypt                  1.010000   0.000000   1.010000 (  1.035354)\n\n```\n\n## Smaller cookies\n\nA welcome consequence is that of smaller cookies. This isn't strictly the result of changed encryption algorithms, but CookieStore's message packing is somewhat ineffecient. It is effectively:\n\n    Base64(Base64(iv) || \"--\" || Base64(message)) || \"--\" HMAC\n\nIf you can understand the reasoning for double Base64 encoding you're smarter than I am, but it adds to the four delimiting bytes. The authenticator on Poly1305 is also four bytes shorter than SHA1. You can see the end result in the above benchmark - 222 bytes vs 128 for our sample.\n\nSmaller cookies are a good thing. It's less data on the wire for every single page hit, and it's more room to move around the 4Kb limit.\n\n## More performant\n\nThe above benchmark shows our approach as much more performant. Some of that is just crypto, which can be hardware dependent.\n\nBut some of this is down to the message packing. Dipping into Base64 functions three separate times to open one cookie is ineffecient. When the IV is known to be of BLOCKSIZE length, choosing to cut it by using split() and a delimiter is the long way around. In the end, performance is great.\n\n## A modern security approach\n\nLet's be clear about the fact that I have no known issue with the current CookieStore implementation. However, it's worth having a read of the view of [Google's Adam Langley](https://www.imperialviolet.org/2013/10/07/chacha20.html) when describing \"a strong motivation to replace it\" when describing CBC mode.\n\nIndeed, the are several comments in the original Rails source code to the effect of \"this dance is done in the hope we don't introduce a vulnerability\". In general, it would be argued that a thin layer of code on libsodium presents a higher quality product than a library over OpenSSL.\n\nWhat you'll find in this gem is a much smaller, more easily audited codebase without any hoops to jump through.\n\n# Approach\n\nThis gem is designed largely as a drop-in replacement for MessageEncryptor, which in turn is used by CookieStore. In a default environment, Rails astracts away everything I say below.\n\nMessageEncryptor takes a \"secret\", and a \"signing secret\", using them as two different secrets. Libsodium only needs a 256-bit secret.\n\nMessageEncryptor offers the option to provide an OpenSSL cipher. Obviously none of these apply to our gem. Finally, MessageEncryptor offers its choice of serializers. It defaults to Marshal, which was always a bad move, so Rails started to implicitly set JSON as the serializer in version 4.1. There's no reason in my view to let people have a footgun like this, so all this gem supports is JSON.\n\nIn order to make this \"drop in\", all the above parameters can still be provided, they are just ignored.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnion%2Fmessagesodium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnion%2Fmessagesodium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnion%2Fmessagesodium/lists"}