manbytesgnu_site

Source files for manbytesgnu.org
git clone git://holbrook.no/manbytesgnu_site.git
Info | Log | Files | Refs

20220112_clortho.rst (7241B)


      1 Secrets in the shell
      2 ####################
      3 
      4 :date: 2024-06-25 20:46
      5 :modified: 2024-06-25 21:58
      6 :category: Code
      7 :author: Louis Holbrook
      8 :tags: crypto,hash,sha512,bash,cli,ccrypt
      9 :slug: clortho
     10 :summary: A key value store at your fingertips
     11 :lang: en
     12 :status: published 
     13 
     14 
     15 Ever since I started using the pass_ CLI as my password manager, I've found myself putting all sorts of stuff in there; usernames, email, urls, crypto addresses, api keys, you name it.
     16 
     17 It makes total sense that some of these items are in there. For example, I store the url to a service together with the password, usually accompanied by the username and the email used [1]_. No password recoveries needed.
     18 
     19 However, at some point I also started putting in things like crypto addresses, or even token smart contract addresses in there.
     20 
     21 That seemed less of a good fit.
     22 
     23 One thing is that it spams the password directory.
     24 
     25 Another, perhaps more sinister, issue is that it's pretty clear for anyone reading the directory what items you are storing data for.
     26 
     27 So what if I want to store key/value pairs, and at the same time I want to hide what I am storing? 
     28 
     29 
     30 Hiding in plain cipher text
     31 ===========================
     32 
     33 
     34 A simple solution is to hash the key together with some passphrase as "salt", along the lines of this:
     35 
     36 .. code-block:: bash
     37         
     38         key=$1
     39         # read passphrase from stdin
     40 	stty -echo
     41 	echo -n "passphrase: "
     42 	read passphrase
     43 	stty echo
     44         hash_key() {
     45                 # dump the passphrase (assuming mktemp stores in volatile memory)
     46                 ktt=$(mktemp)
     47                 kt=$(mktemp)
     48                 chmod 200 $kt
     49                 echo $passphrase > $kt
     50                 chmod 600 $kt
     51                 # the salted key; first add the hashed passphrase (sha512)
     52                 kc=$(sha512sum $kt | awk '{print $1;}' > $ktt)
     53                 # remove the stored passphrase 
     54                 shred $kt
     55                 # then add the key to the mix, and hash again
     56                 echo $kp >> $ktt
     57                 kc=$(sha512sum $ktt | awk '{print $1;}')
     58         }
     59 
     60 The ``kc`` variable at the end of the script above now contains the *salted* hash of the key.
     61 
     62 Specifically, in this implementation, given key ``"foo"`` and passphrase ``"bar"``, the resulting key will be:
     63 
     64 ``a9454592edbed78c3abb739dd88567bc92cc4ea1feee8480c7204d48d7d0e9ce86f9c79d55e39751ceb3f2774913841056293a5e8e8f440a3f281dffabd6f540``.
     65 
     66 
     67 Added value
     68 ===========
     69 
     70 Now we can encrypt the store the corresponding value, and store it in a file that has that literal hash as the key.
     71 
     72 Using ccrypt_ as an example:
     73 
     74 .. code-block:: bash
     75 
     76         data_dir=$HOME/.obfuscated
     77         key=$1
     78         vp=$2
     79         echo -n "$vp" > $t
     80         # create a file for ccrypt to read, because supplying any other way in shell is not so safe.
     81 	passfile=$(mktemp)
     82 	chmod 600 $passfile
     83 	echo -n $passphrase > $passfile
     84 	chmod 400 $passfile
     85 	ccrypt -k $passfile $t
     86         shred $passfile
     87 	if [ "$?" -gt "0" ]; then
     88 		>&2 echo set key fail
     89 		exit 1
     90 	fi
     91         # run the code in the previous section
     92 	hash_key
     93         mkdir -vp $data_dir
     94 	cp $t.cpt $data_dir/$kc
     95 	shred $t.cpt
     96 
     97 At the end of this operation, the *encrypted* value is stored in a file whose name is the *salted* hash of the key.
     98 
     99 
    100 
    101 Key Mastering
    102 -------------
    103 
    104 Let's say you want to store some `Ethereum addresses`_ that are of interest to you, but should be of interest to noone else.
    105 
    106 So, let's choose a prefix for "Ethereum addresses." Let it be ``etha``
    107 
    108 Next, let's pick an identifier that we will remember, that describes the *purpose* of the address. In this case it's for "governance of the organization 'Xy Zzy Co.'". The key then becomes ``ethagovxyzzyco``.
    109 
    110 Last, for a bit of extra fun, let's add some random stuff at the end of the string, like `shilling!shilling?oh,shilling <https://www.quotes.net/mquote/42425>`_. Thus, we finally end up with `ethagovxyzshilling!shilling?oh,shilling``.
    111 
    112 What we need to memorize here is:
    113 
    114 * whenever referring to an *Ethereum address*. we use ``etha``
    115 * whenever referring to *governance*. we use ``gov``
    116 * whenever referring to an entity, we use the name of the organization *less whitespace and special characters*.
    117 * the three above are added one after another
    118 * add the extra fun
    119 
    120 There will of course always be a pattern to how you create and add similar structures for other categories, actions and entities.
    121 
    122 But the point here is to show that it doesn't take *that much* to have some advantage of *plausible deniability*: Even faced with the `5 Dollar Wrench Problem`_, if you are able to hold your ground, there is no feasible way to prove that you *don't own something*. Bite the bullet, absorb the pain, deny ownership, and you'll be fine.
    123 
    124 
    125 Perils and pitfalls
    126 ===================
    127 
    128 None of this is in no way safe by itself.
    129 
    130 Some concerns are named below. Surely there are others, too.
    131 
    132 
    133 Out of sight, but still mined
    134 -----------------------------
    135 
    136 You may find it a pain in the ass to type the passphrase for the key salt every time.
    137 
    138 An obvious workaround for that is to store the passphrase in a file.
    139 
    140 But keep in mind that, if you do that, the key obfuscation is going to be less safe than your regular passwords storage.
    141 
    142 That is to say: If the attacker can read your passwords ciphertext, most likely the attacked can read you obfuscation passphrase, too.
    143 
    144 
    145 Out of mind, out of luck
    146 ------------------------
    147 
    148 Maybe the most important thing to realize in this solution is that there is no way to recall the original keys from the file names under which the values are stored.
    149 
    150 Instead, the idea is that you decide on a naming scheme for certain crucial values you want to store, and *remember* how to reconstruct them. [2]_
    151 
    152 
    153 Shell shill
    154 -----------
    155 
    156 The code above has been adapted from a ``bash`` tool I've already written for the purpose, given the name Clortho_.
    157 
    158 Shell script is surely a very poor choice for this kind of thing, but at the time I simply wanted to write shell so that's how it ended up.
    159 
    160 I probably will rewrite it for another environment at some point.
    161 
    162 But for now it illustrates the point.
    163 
    164 
    165 ..
    166 
    167         .. [1] I use a different email for each service I sign up to, and for every other context I have to leave my email for something. I highly recommend this practice, aswell as running your own mail server. `It really isn't that hard <https://www.linuxbabe.com/mail-server/setup-basic-postfix-mail-sever-ubuntu>`_.
    168 
    169 
    170 ..
    171 
    172         .. [2] I'm not going to lie: That kind of thing takes practice. As in, you need to remind yourself from time to time what your scheme is. Perhaps that is an unthinkable proposition in the age of the Smartphone and the illusion of auxiliary instant truths. But I come from a time where I knew all numbers and addresses I needed to know by heart. The more you do it, the more you remember. The less you do it, the more you are dependent on others. What others do you depend on? And so on it goes...
    173 
    174 .. _pass: https://www.passwordstore.org/
    175 
    176 .. _ccrypt: https://ccrypt.sourceforge.net/
    177 
    178 .. _Clortho: https://holbrook.no/src/clortho/file/clortho.sh.html#l10
    179 
    180 .. _5 Dollar Wrench Problem: https://xkcd.com/538/
    181 
    182 .. _Ethereum addresses: https://kobl.one/blog/create-full-ethereum-keypair-and-address/