{"id":450,"date":"2016-12-14T03:04:35","date_gmt":"2016-12-14T03:04:35","guid":{"rendered":"http:\/\/tuxlabs.com\/?p=450"},"modified":"2016-12-14T17:54:54","modified_gmt":"2016-12-14T17:54:54","slug":"security-securely-storing-passwords-using-pass-gpg","status":"publish","type":"post","link":"https:\/\/tuxlabs.com\/?p=450","title":{"rendered":"Storing passwords securely using Pass (GPG)"},"content":{"rendered":"<p>Today we\u00a0live in an endless sea\u00a0of passwords, which are a very inefficient and ineffective means of securing our data &amp; environments. Many companies are trying to solve this problem using a variety of techniques that all revolve around various forms of multi-factor authentication.<\/p>\n<blockquote><p>However, in the mean time were all screwed \ud83d\ude09<\/p><\/blockquote>\n<p><strong>Just kidding.<\/strong> Quick PSA though, use two factor authentication at a minimum everywhere you can ESPECIALLY your email, since it&#8217;s used for password recovery on other sites. Ok then moving on&#8230;<\/p>\n<p>There are many password managers like LastPass and 1Password, which do a fairly effective job at providing convenience and prevent you from scribbling down your passwords on paper (STOP IT !!!). However, I personally can&#8217;t get passed the whole &#8216;store all my passwords in one super secure vault on the Internet&#8217; thing. To be fair some of these password managers can be downloaded on your machine and ran locally, but there are two\u00a0other drawbacks to those I found.<\/p>\n<ol>\n<li>Some of them are not free and&#8230;<\/li>\n<li>Some of them have\u00a0ugly and clunky UI&#8217;s<\/li>\n<\/ol>\n<p>So what do I like\/use then ? I use something called &#8216;pass&#8217;. Which is a command line utility that wraps GPG. The reason I use it is because&#8230;<\/p>\n<ol>\n<li>I love using command line utilities over GUI, I find it far more convenient and&#8230;<\/li>\n<li>I was going to write this exact utility (a GPG wrapper) until I found out someone else did and&#8230;<\/li>\n<li>Because I like\u00a0GPG.<\/li>\n<\/ol>\n<p>At most of the organizations I have worked at, password management was done poorly i.e. everyone\u00a0used different approaches and there was no governance or oversight. I hope with this article to make folks aware of what I feel is a simple, effective method that every unix savvy administrator\u00a0should use.<\/p>\n<blockquote><p>FYI Pass provides migration scripts\u00a0from\u00a0the most\u00a0popular password manager tools\u00a0on their website.<\/p><\/blockquote>\n<h2>Introducing Pass<\/h2>\n<p>From the Pass site &#8220;Password management should be simple and follow <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unix_philosophy\">Unix philosophy<\/a>. With <code>pass<\/code>, each password lives inside of a <a href=\"http:\/\/en.wikipedia.org\/wiki\/GNU_Privacy_Guard\"><code>gpg<\/code><\/a> encrypted file whose filename is the title of the website or resource that requires the password. These encrypted files may be organized into meaningful folder hierarchies, copied from computer to computer, and, in general, manipulated using standard command line file management utilities.&#8221;<\/p>\n<p><strong>Where Can You Get\u00a0or Learn More About Pass ?\u00a0<\/strong><\/p>\n<p><a href=\"https:\/\/www.passwordstore.org\/\">https:\/\/www.passwordstore.org\/<\/a><\/p>\n<h2>Installing Pass<\/h2>\n<p>Depending on your operating system there are various ways to install<\/p>\n<p><strong>Ubuntu\/Debian<\/strong><\/p>\n<pre class=\"lang:default decode:true\">sudo apt-get install pass<\/pre>\n<p><strong>Fedora \/ RHEL<\/strong><\/p>\n<pre class=\"lang:default decode:true\">sudo yum install pass<\/pre>\n<p><strong>Mac<\/strong><\/p>\n<pre class=\"lang:default decode:true\">brew install pass\r\necho \"source \/usr\/local\/etc\/bash_completion.d\/password-store\" &gt;&gt; ~\/.bashrc<\/pre>\n<p>Since I already installed pass on my Mac a while back I will be installing it on a Docker container with Ubuntu 16.04.<\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:\/# apt-get install -y pass<\/pre>\n<p>After pass successfully installs, try running it<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:\/# pass\r\nError: password store is empty. Try \"pass init\".\r\nroot@0b415380eb80:\/#<\/pre>\n<p>Well that is pretty straight forward, it appears we need to initiliaze the db.<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:\/# pass init\r\nUsage: pass init [--path=subfolder,-p subfolder] gpg-id...\r\nroot@0b415380eb80:\/#<\/pre>\n<p>Looks like we need to provide &#8216;key&#8217;&#8230;can that be just anything?<\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:\/# pass init \"tuxlabs Password Key\"\r\nmkdir: created directory '\/root\/.password-store\/'\r\nPassword store initialized for tuxlabs Password Key\r\nroot@0b415380eb80:\/# pass\r\nPassword Store\r\nroot@0b415380eb80:\/#<\/pre>\n<p>Now our password store looks initialized ! Let&#8217;s try inserting a password into the DB !<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:\/# pass insert Gmail\/myemail\r\nmkdir: created directory '\/root\/.password-store\/Gmail'\r\nEnter password for Gmail\/myemail:\r\nRetype password for Gmail\/myemail:\r\ngpg: tuxlabs Password Key: skipped: No public key\r\ngpg: [stdin]: encryption failed: No public key\r\nroot@0b415380eb80:\/#<\/pre>\n<p>Uh oh what happened ? Well remember I said it uses GPG, and we not only don&#8217;t have a gpg key setup in our Docker container, but we initialized our Pass DB without using a GPG Key (the whole point) !<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:\/# gpg --list-keys\r\nroot@0b415380eb80:\/#<\/pre>\n<p>To remedy this we need to create a GPG key<\/p>\n<h3>Creating your GPG Key<\/h3>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:\/# gpg --gen-key\r\ngpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.\r\nThis is free software: you are free to change and redistribute it.\r\nThere is NO WARRANTY, to the extent permitted by law.\r\n\r\nPlease select what kind of key you want:\r\n   (1) RSA and RSA (default)\r\n   (2) DSA and Elgamal\r\n   (3) DSA (sign only)\r\n   (4) RSA (sign only)\r\nYour selection? 1\r\nRSA keys may be between 1024 and 4096 bits long.\r\nWhat keysize do you want? (2048) 4096\r\nRequested keysize is 4096 bits\r\nPlease specify how long the key should be valid.\r\n         0 = key does not expire\r\n      &lt;n&gt;  = key expires in n days\r\n      &lt;n&gt;w = key expires in n weeks\r\n      &lt;n&gt;m = key expires in n months\r\n      &lt;n&gt;y = key expires in n years\r\nKey is valid for? (0)\r\nKey does not expire at all\r\nIs this correct? (y\/N) y\r\n\r\nYou need a user ID to identify your key; the software constructs the user ID\r\nfrom the Real Name, Comment and Email Address in this form:\r\n    \"Heinrich Heine (Der Dichter) &lt;heinrichh@duesseldorf.de&gt;\"\r\n\r\nReal name: Tuxninja\r\nEmail address: tuxninja@tuxlabs.com\r\nComment: TuxLabs\r\nYou selected this USER-ID:\r\n    \"Tuxninja (TuxLabs) &lt;tuxninja@tuxlabs.com&gt;\"\r\n\r\nChange (N)ame, (C)omment, (E)mail or (O)kay\/(Q)uit? O\r\nYou need a Passphrase to protect your secret key.\r\n\r\ngpg: gpg-agent is not available in this session\r\nWe need to generate a lot of random bytes. It is a good idea to perform\r\nsome other action (type on the keyboard, move the mouse, utilize the\r\ndisks) during the prime generation; this gives the random number\r\ngenerator a better chance to gain enough entropy.\r\n............+++++\r\n...................+++++\r\nWe need to generate a lot of random bytes. It is a good idea to perform\r\nsome other action (type on the keyboard, move the mouse, utilize the\r\ndisks) during the prime generation; this gives the random number\r\ngenerator a better chance to gain enough entropy.\r\n...+++++\r\n+++++\r\ngpg: key 5B2F89A5 marked as ultimately trusted\r\npublic and secret key created and signed.\r\n\r\ngpg: checking the trustdb\r\ngpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model\r\ngpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u\r\npub   4096R\/5B2F89A5 2016-12-14\r\n      Key fingerprint = 5FF6 1717 4415 03FF D455  7516 CF8E 1BDC 5B2F 89A5\r\nuid                  Tuxninja (TuxLabs) &lt;tuxninja@tuxlabs.com&gt;\r\nsub   4096R\/EF0F232F 2016-12-14\r\n\r\nroot@0b415380eb80:\/#<\/pre>\n<p>To view your GPG key run<\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:\/# gpg --list-keys\r\n\/root\/.gnupg\/pubring.gpg\r\n------------------------\r\npub   4096R\/5B2F89A5 2016-12-14\r\nuid                  Tuxninja (TuxLabs) &lt;tuxninja@tuxlabs.com&gt;\r\nsub   4096R\/EF0F232F 2016-12-14\r\n\r\nroot@0b415380eb80:\/#<\/pre>\n<p>Now we can see we have one GPG key, with the ID 5B2F89A5<\/p>\n<p><strong>Let&#8217;s try re-initializing Pass.\u00a0<\/strong><\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:\/# pass init \"5B2F89A5\"\r\nPassword store initialized for 5B2F89A5\r\nroot@0b415380eb80:\/#<\/pre>\n<p>But we have a problem, re-initializing Pass doesn&#8217;t get rid of our previous insert into the db. As you can see here our Pass DB is effectively corrupt.<\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:~# pass\r\nPassword Store\r\n`-- Gmail\r\nroot@0b415380eb80:~# pass rm Gmail\r\nAre you sure you would like to delete Gmail? [y\/N] y\r\nrm: cannot remove '\/root\/.password-store\/Gmail': Is a directory\r\nroot@0b415380eb80:~# pass rm Gmail\/myemail\r\nError: Gmail\/myemail is not in the password store.\r\nroot@0b415380eb80:~#<\/pre>\n<blockquote><p>Hmmm, what&#8217;s a guy to do&#8230;.<\/p><\/blockquote>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:~# rm -rf .password-store\/Gmail\/\r\nroot@0b415380eb80:~# pass\r\nPassword Store\r\nroot@0b415380eb80:~#<\/pre>\n<p>Yes it really was that simple, and that is one more reason why I love pass.<\/p>\n<blockquote><p>You can also initialize your password store using git for version control, see the passwordstore.org website for more info !<\/p><\/blockquote>\n<p>Now let&#8217;s insert some good stuff.<\/p>\n<h3>Inserting A Password into Pass<\/h3>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:~# pass insert Gmail\/myemail\r\nEnter password for Gmail\/myemail:\r\nRetype password for Gmail\/myemail:\r\nroot@0b415380eb80:~# pass\r\nPassword Store\r\n`-- Gmail\r\n    `-- myemail\r\nroot@0b415380eb80:~#<\/pre>\n<p>That seems to have worked. Let&#8217;s try to retrieve the pass.<\/p>\n<h3>Retrieving A Password In Pass<\/h3>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:~# pass Gmail\/myemail\r\ngpg: starting migration from earlier GnuPG versions\r\ngpg: porting secret keys from '\/root\/.gnupg\/secring.gpg' to gpg-agent\r\ngpg: migration succeeded\r\ntestpass\r\nroot@0b415380eb80:~# pass Gmail\/myemail\r\ntestpass\r\nroot@0b415380eb80:~#<\/pre>\n<p>Note, I retrieve the password twice using my GPG Passsword (You will be prompted through a curses interface to enter your passphrase). Then I run it again, because of the initial GPG migration messages just to show how it would normally work after you&#8217;ve used GPG once with Pass.<\/p>\n<p>Now let&#8217;s say someone is standing over your shoulder, you want to access your passsword, but you don&#8217;t want them to see it. You can get it straight to your clipboard by using -c.<\/p>\n<h3>Copying Passwords To Your Clipboard<\/h3>\n<pre class=\"lang:default decode:true \">pass -c Gmail\/myemail\r\nCopied Gmail\/myemail to clipboard. Will clear in 45 seconds.<\/pre>\n<h4>Docker\u00a0Issue ?<\/h4>\n<p>Notice the prompt is not included in the above example ? That is cause it didn&#8217;t actually work. Apparently, it doesn&#8217;t work in Docker due to not having display dependencies installed\/configured. So what I show above is the output from my mac&#8230;but my actual Docker related error was.<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:~# pass -c Gmail\/myemail\r\nError: Can't open display: (null)\r\nError: Could not copy data to the clipboard\r\nroot@0b415380eb80:~#<\/pre>\n<p>There might be an easy way to fix this (like install X), but I don&#8217;t usually use Docker for storing my passwords I just happen to be using it for this tutorial, so moving on !<\/p>\n<h3>Folders<\/h3>\n<p>It&#8217;s also important to note that Pass supports folder structures, as shown in my example I am creating a &#8216;Gmail&#8217; folder and placing a password file called &#8216;myemail&#8217; with my password in it. In reality I recommend not naming the file after your account\/email and using the multiline version to encrypt those details as well. That way you can just stick to the site name for the name of the encrypted file in whatever folder or in the top level of Pass.<\/p>\n<h3>Multiline Encrypted Files with Pass<\/h3>\n<p>A common use case with Pass is adding an entire encrypted file so you can store more than just a password&#8230;<\/p>\n<pre class=\"lang:default decode:true \">root@0b415380eb80:~# pass insert -m tuxlabs\/databases\r\nmkdir: created directory '\/root\/.password-store\/tuxlabs'\r\nEnter contents of tuxlabs\/databases and press Ctrl+D when finished:\r\n\r\nthis is an example of a multiline\r\nencrypted file\r\nthis way you can store more than just a password you can store user\/pass\/url etc\r\nroot@0b415380eb80:~# pass\r\nPassword Store\r\n|-- Gmail\r\n|   `-- myemail\r\n`-- tuxlabs\r\n    `-- databases\r\nroot@0b415380eb80:~#<\/pre>\n<p>Again retrieving it is as easy as..<\/p>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:~# pass tuxlabs\/databases\r\nthis is an example of a multiline\r\nencrypted file\r\nthis way you can store more than just a password you can store user\/pass\/url etc\r\nroot@0b415380eb80:~#<\/pre>\n<p>Finally if you no longer want the info to be stored in Pass&#8230;<\/p>\n<blockquote><p>If you want to copy you password\u00a0to the clipboard from a multiline file, you must store your password on the first line of the file !<\/p><\/blockquote>\n<h3>Deleting An Entry In Pass<\/h3>\n<pre class=\"lang:default decode:true\">root@0b415380eb80:~# pass rm Gmail\/myemail\r\nAre you sure you would like to delete Gmail\/myemail? [y\/N] y\r\nremoved '\/root\/.password-store\/Gmail\/myemail.gpg'\r\nroot@0b415380eb80:~# pass rm tuxlabs\/databases\r\nAre you sure you would like to delete tuxlabs\/databases? [y\/N] y\r\nremoved '\/root\/.password-store\/tuxlabs\/databases.gpg'\r\nroot@0b415380eb80:~# pass\r\nPassword Store\r\nroot@0b415380eb80:~#<\/pre>\n<p>Another thing, the output on my mac is much prettier\u00a0than this `&#8211; thing I am getting in the Ubuntu Docker container&#8230; Not sure if that&#8217;s an Ubuntu issue or Docker, but on the Mac the output is much prettier, which can be seen on the passwordstore.org home page.<\/p>\n<p>So that&#8217;s it, Pass is pretty straight forward, easy to work with, depends on GPG security and that is why I like it.<\/p>\n<p>Stay secure, until next time !<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<a href=\"https:\/\/tuxlabs.com\/?p=450\" rel=\"bookmark\" title=\"Permalink to Storing passwords securely using Pass (GPG)\"><p>Today we\u00a0live in an endless sea\u00a0of passwords, which are a very inefficient and ineffective means of securing our data &amp; environments. Many companies are trying to solve this problem using a variety of techniques that all revolve around various forms of multi-factor authentication. However, in the mean time were all screwed \ud83d\ude09 Just kidding. Quick [&hellip;]<\/p>\n<\/a>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61,157,78],"tags":[158,161,159,162,160,104],"class_list":{"0":"post-450","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-encryption","7":"category-perspectives","8":"category-security","9":"tag-docker","10":"tag-gpg","11":"tag-pass","12":"tag-passwords","13":"tag-security","14":"tag-ubuntu","15":"h-entry","16":"hentry"},"_links":{"self":[{"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/450","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=450"}],"version-history":[{"count":24,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/450\/revisions"}],"predecessor-version":[{"id":474,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/450\/revisions\/474"}],"wp:attachment":[{"href":"https:\/\/tuxlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=450"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=450"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tuxlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=450"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}