Safe Haskell | None |
---|---|
Language | Haskell2010 |
Goal
Hide sensitive data inside text files in a readable and compact manner.
Requirements
- Support various encryption/key-storing mechanisms (per encrypted value)
- Adding new portion of secrets to already encrypted text file does not modify previously encrypted values
- Only sensitive data is hidden, the rest is left intact.
- Ciphered values should not be part of the file (in order to make it readable and compact).
- Same ciphered value could be referenced many times.
- [TODO] Same ciphered value could be referenced in many files.
Solution
Assume there is a file config
containing some sensitive data.
host = "localhost" user = "foobar" password = "5fce4e0edf2242e981f799b1d8e0dc62"
In order to hide sensitive data it's need to be wrapped with a Plain value
identifier.
host = "localhost" user = "{{P|username|gpgme|kid = keyId|foobar}}" password = "{{P|password|gpgme|kid = keyId|5fce4e0edf2242e981f799b1d8e0dc62}}"
For instance, {{P|username|gpgme|kid = keyId|foobar}}
means that it's a variable username
with a Plain value foobar that should be encrypted with gpgme algorithm, and there are some arguments (kid = keyId
) that would be needed during encryption process.
After things are set up, encryption could be done.
Here is how config
file look like after encryption:
host = "localhost" user = "{{E|username}}" password = "{{E|password}}"
Metadata file with encrypted values .config.e
:
{ "username": { "alg": "gpgme", "args": { "kid": "keyId" }, "value": "CNMoJrL5jnbgw4UM60Ht+NXoOtdgk8iStAB8D6JAnZHyz6Z7YfdoNs4EyoqMbBhRDlRRpakbtfiIvH1GlcOt7RzQfHzv+ZNQkU2o12naX6uZVw+abJYjpsG50wpkeE8h8W08htNE1JEAsgomojIlRYM973H1aoPqkgS+75fyvdadFVB9yTnSV6qOBwFJOi62wrrHpNCoJMNJMf6OX5OBTaXFSxSPXQc15v6SXh5ryQbOh0VCZdzkAF4UMAiSl84WMhM4XRc8TfcAW3MG6v9ToWX+hPUq+jD14oZpvqWc8lNHMWibcoTt8fxm5BebvX7+8x+L0JA0RYdeSZxFww0QxMAO46slc6BSRPV78ULuS6HAOfUN5zEIXV9e9ru+4sEa+myOJPoNR2fEbxPpYAbUe0UZjKn1Z5iuVtihhnY+gx2alv6Aiv45sG+Xv7qCdnXbW6I0EuI6eOEKeUgP2FHAffRdGkk5Qbc4q74GgjDJPVAZOHppI7QMx3z89ndBEWZ6bTUEkNVBQqy8vusgogoIfOWXrbCr4nwSyx1G3pvNnLJrbt4I4udaSfj8qKWJoZX8BvNl4yJBy5P1XW+E1WJX4pp74oKaI6L9QXrV5HECzec7KwA9CsTmigSZmKasgI5V62q1HiGyfygz7HPwf7EykW0vgq4Qs9R1U=|lvUD" }, "password": { "alg": "gpgme", "args": { "kid": "keyId" }, "value": "NcUeEoRHrl1LrVsYml9R8oZVAaYNv2rCcYLF2RwPHD9i62Xrf9tBiyQLjGSmScGJlbubztHh6ZHEeMv2zEELNMt6N0yc7tGsI4s7aSxVs5LfibwGeKGelZUgv41FiF32SvTTDepL3M20PlPpEwp1lPv8WewWsakPJz6m63x2MinF1l13UvNQ7i61FPkjdYBclmM1oiqaztqPYG6uBINm1WeoKvWe3kEsDfRh4Gwg4J5YSe8rjNwM1wNzrNsj4+FI3abav9TpqQAcGt261TdB3ocdt3L65Cd+KLqnIhDEpCwBUlt747bo4XNXH4Z4Tzpclha4CzNW+jyoDSo6Yddt6wwNn+75NKlkPIOOt2JorZiTFA1MJ97imRIiAfbaz8yzs3WC1lruPtaP2rmslHdGIC9uprrMp7hBoyeYTEwy5QN5lWuJzGq9siKSChrXTyKP6eSQiL6WIN1BquDigOio8N1ezjokkRZZo8ijDERIYciZZuMfEW3kbDZIFx0cBgeM5kfpkK8lCmuMeXM9WxFhNGKkOgrlAFzbukuOqxnOxlHvyrwb7qwWc4zmvz9R+O0twwU8sJjqoDIUliX9nZmAGkG9rKwZhY3AbWN1QAFyPY2+2FfVXm77ZN7x5GCXYQ86ov+yl976mk5jGqyg5CHKYA9673ruA=|VpMaDn9r0II=" } }
Encrypted file config
could be decrypted back using the same metadata:
host = "localhost" user = "foo" password = "5fce4e0edf22"
🎉
- module E.Template
- module E.Metadata
- module E.Encrypt
- module E.Action
- module E.Algorithm.Dummy
- module E.Describe
- pack :: String -> Text
- module Control.Monad.Trans.Either
Template - representation of an encrypted or to-be-encrypted content.
module E.Template
Metatada - ciphered values store
module E.Metadata
Cipher values from Tem
using Metadata
module E.Encrypt
Cipher actions on the filesystem
module E.Action
Simplest instance of Algs
module E.Algorithm.Dummy
Errors
module E.Describe
Reexports
module Control.Monad.Trans.Either