Skip to content

Passh filename encryption

HacKan edited this page Jul 20, 2017 · 2 revisions

The following is intended for developers or advanced users.

Project

The idea of this project is to solve the meta-data leak by encrypting file-names and directories somehow, including commit messages.

The action of rendering the names unreadable without having the key is called lock the store. The action of making the names readable is called unlock the store.

Help wanted!

WIP: branch encrypt-filenames.
Project page: Passh file-name encryption.

Objectives

  • Transparently solve meta-data leak, by encrypting file-names and directories, allowing the use of git w/o exposing private information.
  • Easy of use.

Characteristics

  • It must be able, for every GPG key in the store, to read file-names and directories.
  • It must be transparent for the user: auto-completion must work, issuing passh must list clear text entries (default show command), etc.
  • It must be possible to "manually" decrypt file-names/directory names, with nothing more than standard tools. A recovery/undo tool must be provided for simplicity.
  • It should be optional: Passh should be able to operate on stores with and without this characteristics.
  • It must be possible to undo/redo: going back and forth encrypting and decrypting the store, automatically (probably with passh init).
  • The implementation should use well-known crypto primitives, and must be simple.

Solutions

These solutions are thought for Linux-based systems. Porting them to MacOS shouldn't be hard, but Windows might be a problem.

Proposed solution 1

I propose a simple 1:1 encryption model, where names are encrypted using GPG symmetric encryption and base64url encoded.

I.E.: an entry such as webs/facebook.com would be encrypted as jA0ECQMKbp9FgeNHtKju0jUBch3RTouSV2loi3c6LL-C5ZZeO8ouiB91F6woLN_xTMZ7xvTp4PRNANEuuWIIXhLwIQvryQ==/jA0ECQMKu-ytdOlkfTTu0j0B8t7NkcKOGk0WbGML5Z6l_JEfuwdruTtOvSMicwqXKgeJnxceWxXb9b8HHBh2rAx3V2l3yJ0nDOT0fn3P (which you can decrypt yourself: echo ${b64url_string} | sed -e 's/-/+/g; s/_/\//g' | base64 -d | gpg --decrypt, the password is passh).

The store is moved to a different location, appending -enc to the previous location (it's user configurable): by default, the store is in ~/.password-store, so it's moved to ~/.password-store-enc.

When unlocked, softlinks are used to represent the whole store in ~/.password-store (or the corresponding location without -enc). To avoid writing in insecure space, /dev/shm is used: /dev/shm/$USER/$PASSWORD_STORE_DIR, which is linked to by ~/.password-store: ~/.password-store -> /dev/shm/hackan/.password-store. This way, the unlocked store is actually a collection of dirs and softlinks to the encrypted store, i.e.: ~/.password-store/webs/facebook.com -> ~/.password-store-enc/jA0E...yQ==/jA0E...fn3P.gpg.

When locked, the whole directory in /dev/shm/$USER/$PASSWORD_STORE_DIR is removed.

Advantages

  • Simple, allows easy manual (or scripted) recovery with standard tools.
  • Does not depend on any additional file or resource.

Disadvantages

  • Leaks some meta-data in a public git repository:
    • Timestamp of each commit, which implies timestamp of file(s) modification.
    • The total amount of entries in the store.
    • The directory tree: some conclusions and estimations can be done with this info.
    • When, if and how many times is each entry modified.
    • Who modifies each entry (for a multi-user case).

Details

Terms:

  • PT = Plaintext
  • CT = Ciphertext / Encrypted text
  • MK = Master key
  • PK = GPG Pub key
  • SK = GPG Sec key

The symbol -> denotes "softlink to"

Name encryption

OUT = BASE64URL(GPG_SYMMETRIC(PT, MK, OPTIONS))

OPTIONS = {
cipher-algo aes256,
compression-algo 0,
s2k-mode 3,
s2k-digest-algo SHA512
}

MK generation (1): Derive from GPG SK

MK = ARGON2i(NONCE, SK, OPTIONS)

len(NONCE) >= 16

OPTIONS = {
t 3,
p 1,
m 19,
l 32
}

Advantages:

  • No additional resources needed if fixed nonce is used.

Disadvantages:

  • Requires to store random nonce.
    • SK FPR can be used instead of a random nonce; I found no issue in Argon2 paper regarding the use of a known nonce instead of a random one (please contact me urgently if this isn't correct).
  • Can't be used with shared stores.

MK generation (2): Random key

Generate a random key, store it encrypted.

Advantages:

  • Works for shared stores (multiple GPG keys).

Disadvantages:

  • Heavily affected by randomness issues.
  • Requires storing it.
  • If missing, store is doomed.

Proposed solution 2

Each Passh entry is stored as a single file with a long random name. An encrypted database (SQLITE3) is used to link those file names to entries.

I.E.: an entry such as webs/facebook.com would be in a file named 0d6f59a6f9a8790b5e70e7d04a9819e930f9d9dfedbb9b07dca3ca67cd8ca9c84898317187644c218cedaffd15196bedee5e63a4f40ab72d08cc09ddbbac5b08, and an entry to the linking database is created.

The store is moved to a different location, appending -enc to the previous location (it's user configurable): by default, the store is in ~/.password-store, so it's moved to ~/.password-store-enc.

When unlocked, softlinks are used to represent the whole store in ~/.password-store (or the corresponding location without -enc). To avoid writing in insecure space, /dev/shm is used: /dev/shm/$USER/$PASSWORD_STORE_DIR, which is linked to by ~/.password-store: ~/.password-store -> /dev/shm/hackan/.password-store. This way, the unlocked store is actually a collection of dirs and softlinks to the encrypted store, i.e.: ~/.password-store/webs/facebook.com -> ~/.password-store-enc/0d6f5...c5b08.gpg.

When locked, the whole directory in /dev/shm/$USER/$PASSWORD_STORE_DIR is removed.

Advantages

  • Leaks less data than the solution 1.

Disadvantages

  • Very complex solution, requires a database and its maintenance.
  • If the database file becomes corrupted, the store is doomed.
  • Requires advance knowledge for disaster recovery: browsing through the SQLITE3 DB.
  • Leaks some meta-data in a public git repository:
    • Timestamp of each commit, which implies timestamp of file(s) modification.
    • The total amount of entries in the store.
    • When, if and how many times is each entry modified.
    • Who modifies each entry (for a multi-user case).