<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Aaron Toponce &#187; Security</title>
	<atom:link href="http://pthree.org/category/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://pthree.org</link>
	<description>Linux.  GNU.  Freedom.</description>
	<lastBuildDate>Sun, 05 Feb 2012 14:33:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4-alpha</generator>
		<item>
		<title>Encrypted Mutt IMAP/SMTP Passwords</title>
		<link>http://pthree.org/2012/01/07/encrypted-mutt-imap-smtp-passwords/</link>
		<comments>http://pthree.org/2012/01/07/encrypted-mutt-imap-smtp-passwords/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 15:16:56 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2183</guid>
		<description><![CDATA[Rather than storing your IMAP and SMTP passwords in plain text on disk, you can store them encrypted using GnuPG, OpenSSL, the GNOME Keyring, or any other method of password storage encryption. It still requires a &#8220;master password&#8221; from you to decrypt the file(s) on the fly, and set the appropriate passwords, but then it [...]]]></description>
			<content:encoded><![CDATA[<p>Rather than storing your IMAP and SMTP passwords in plain text on disk, you can store them encrypted using GnuPG, OpenSSL, the GNOME Keyring, or any other method of password storage encryption. It still requires a &#8220;master password&#8221; from you to decrypt the file(s) on the fly, and set the appropriate passwords, but then it will remain in RAM in plain text for the duration Mutt is running, and no worries about the password in plain text going to disk.</p>
<p>Here&#8217;s how I set mine up using my GnuPG key. First, I created a ~/.mutt/passwords file. The file is in plain text. Before encrypting it, here are its contents:</p>
<pre>set imap_pass="password"
set smtp_pass="password"</pre>
<p>I then encrypt that file with the following command:</p>
<pre>% gpg -r your.email@example.com -e ~/.mutt/passwords
% ls ~/.mutt/passwords*
/home/user/.mutt/passwords /home/user/.mutt/passwords.gpg
% shred ~/.mutt/passwords
% rm ~/.mutt/passwords</pre>
<p>The last two commands are to ensure that the temporary file you created for encryption is securely wiped from the disk using the GNU Shred utility. Now, you should only have an encrypted binary data file that contains your passwords. All that is left is to configure Mutt to decrypt them when starting up. You can set that easily in your Muttrc:</p>
<pre>source "gpg -d ~/.mutt/passwords.gpg |"</pre>
<p>The string is just a standard string. Also, it&#8217;s important to have &#8220;|&#8221; at the end of the command, to pipe the output to Mutt, so it can be appropriately sourced.</p>
<p>At this point, you should be able to launch Mutt, be asked for the passphrase for your private GnuPG key, and it should log you in to your IMAP account. You should also be able to send mail as normal, logging automatically into your SMTP account. The only time you are asked for a password, is your GnuPG passphrase when starting Mutt. If your &#8220;gpg-agent&#8221; is already running, and you&#8217;ve configured GnuPG to use the agent and added your private key to it, then starting Mutt won&#8217;t ask you for your key passphrase, and will use the agent instead.</p>
<p>Other than temporarily creating the plain text file to encrypt, which stores your passwords, and which you promptly and securely shred later, your IMAP/SMTP passwords for your remote account are never on disk in plain text.</p>
<p>Happy encrypted hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2012/01/07/encrypted-mutt-imap-smtp-passwords/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Making Sense of Hashed Hosts in ~/.ssh/known_hosts</title>
		<link>http://pthree.org/2011/12/30/making-sense-of-hashed-hosts-in-sshknown_hosts/</link>
		<comments>http://pthree.org/2011/12/30/making-sense-of-hashed-hosts-in-sshknown_hosts/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 21:19:57 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2168</guid>
		<description><![CDATA[I don&#8217;t expect you to follow this post completely, but it&#8217;s so amazingly cool, I have to blog it. Consider the hashed sections of ~/.ssh/known_hosts file for (recent) OpenSSH clients, not including the public key parts: &#124;1&#124;kFJT5z0x3ndyutgZ4E5pRk+ORBA=&#124;hzXvdYUudo+qK9BGlFWtSAUXlXc= &#124;1&#124;8wo1+FO0hkATPgQZoeNHeIlvAjw=&#124;dt/a9jz9CnLKP72j+Jr8MKMjgEE= &#124;1&#124;pvBQEKEGLnH0RCJr+8Dmqqnvlrs=&#124;fJJvjyG/TmHFnuIX57nDThq/C4M= &#124;1&#124;HKV4DzgDkajXoUHf9B82JBu7J10=&#124;c/K+MdJvWaZeJFs/W7iqhqo0wvE= &#124;1&#124;rtvQhRVnNanQZYkLUMbjoBGNhn0=&#124;0U6a1LUQqLL6P1T2Wji3VWw69pw= &#124;1&#124;0ziSYi4c+xBXGEBZcNN1LMhYUc4=&#124;qRSN5GSPyQi+fmaVz2zNwkmKoy8= &#124;1&#124;6nv6Vpk3AYgICHxJGVgVdsYRuq0=&#124;fBNOIz1l3RW+N61jyDPunKX9n7E= &#124;1&#124;+b4uA+Mq7RHRAFW21qv8aO3rIRs=&#124;1eizMri01IxEKrXquBnwTYP61Ow= &#124;1&#124;BkB0PZu2qtsLID/Ibe/D68gANQU=&#124;qW6uAzcpecOOKNI4zEvngyfpGkI= &#124;1&#124;n+QrRn7QXeAJ5hRe2M8v8IspihE=&#124;EqUxXdSeIF1cl1fQjl5zILebkGY= &#124;1&#124;BOKuKnWojy028tJf9Y671lws0d0=&#124;SuBQJmJZp5JNVYG/rP9yb9ZhJcE= &#124;1&#124;WACsxtodOiM89kf4rNPLgF1CXZ4=&#124;UTccVeLDZJF3wlH8V05XJNlsOBw= &#124;1&#124;o6FFoirXYblM7wBMdeJDYGMPI58=&#124;5jJB7T7itY702ZHHByXtSpGk9SE= The column fields are similar to [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t expect you to follow this post completely, but it&#8217;s so amazingly cool, I have to blog it. Consider the hashed sections of ~/.ssh/known_hosts file for (recent) OpenSSH clients, not including the public key parts:</p>
<pre>|1|kFJT5z0x3ndyutgZ4E5pRk+ORBA=|hzXvdYUudo+qK9BGlFWtSAUXlXc=
|1|8wo1+FO0hkATPgQZoeNHeIlvAjw=|dt/a9jz9CnLKP72j+Jr8MKMjgEE=
|1|pvBQEKEGLnH0RCJr+8Dmqqnvlrs=|fJJvjyG/TmHFnuIX57nDThq/C4M=
|1|HKV4DzgDkajXoUHf9B82JBu7J10=|c/K+MdJvWaZeJFs/W7iqhqo0wvE=
|1|rtvQhRVnNanQZYkLUMbjoBGNhn0=|0U6a1LUQqLL6P1T2Wji3VWw69pw=
|1|0ziSYi4c+xBXGEBZcNN1LMhYUc4=|qRSN5GSPyQi+fmaVz2zNwkmKoy8=
|1|6nv6Vpk3AYgICHxJGVgVdsYRuq0=|fBNOIz1l3RW+N61jyDPunKX9n7E=
|1|+b4uA+Mq7RHRAFW21qv8aO3rIRs=|1eizMri01IxEKrXquBnwTYP61Ow=
|1|BkB0PZu2qtsLID/Ibe/D68gANQU=|qW6uAzcpecOOKNI4zEvngyfpGkI=
|1|n+QrRn7QXeAJ5hRe2M8v8IspihE=|EqUxXdSeIF1cl1fQjl5zILebkGY=
|1|BOKuKnWojy028tJf9Y671lws0d0=|SuBQJmJZp5JNVYG/rP9yb9ZhJcE=
|1|WACsxtodOiM89kf4rNPLgF1CXZ4=|UTccVeLDZJF3wlH8V05XJNlsOBw=
|1|o6FFoirXYblM7wBMdeJDYGMPI58=|5jJB7T7itY702ZHHByXtSpGk9SE=</pre>
<p>The column fields are similar to that of the /etc/shadow file on GNU systems, except where the &#8220;$&#8221; is the column delimiter, &#8220;|&#8221; is in this case. If the string was &#8220;|1|o6FFoirXYblM7wBMdeJDYGMPI58=|5jJB7T7itY702ZHHByXtSpGk9SE=&#8221;, then the breakdown is as follows:</p>
<ul>
<li><strong>|1</strong>- HASH_MAGIC. This tells the client that the host information has been salted and hashed with the SHA1 algorithm.</li>
<li><strong>|o6FFoirXYblM7wBMdeJDYGMPI58=</strong> This is the salt applied to the host- base 64 encoded 160-bit string.</li>
<li><strong>|5jJB7T7itY702ZHHByXtSpGk9SE=</strong> This is the base 64 encoded version of the hashed host</li>
</ul>
<p>Now, if you want to get at the actual strings, not base 64 encoded, you could run the following command (I admit, not elegant, and could probably be better solved without nesting, and a single awk(1) statement, but I&#8217;ll get to that later):</p>
<pre>% echo $(echo o6FFoirXYblM7wBMdeJDYGMPI58= | openssl base64 -d | xxd | cut -c 10-48) | sed 's/ //g'
a3a145a22ad761b94cef004c75e24360630f239f
% echo $(echo 5jJB7T7itY702ZHHByXtSpGk9SE= | openssl base64 -d | xxd | cut -c 10-48) | sed 's/ //g'
e63241ed3ee2b58ef4d991c70725ed4a91a4f521</pre>
<p>There you have it. Very cool. Now, the only question is how to apply the salt to the hostname, to get to the hash? I&#8217;m working that out, but I wasn&#8217;t motivated enough to get to it. Of course, there&#8217;s no application to this, that I can tell, unless you want to brute force the known_hosts file.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/12/30/making-sense-of-hashed-hosts-in-sshknown_hosts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steganography</title>
		<link>http://pthree.org/2011/12/15/steganography/</link>
		<comments>http://pthree.org/2011/12/15/steganography/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 23:58:05 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2134</guid>
		<description><![CDATA[I have been familiar with steganography for a number of years. In fact, back when I was in middle school, I developed a fascination for encryption, and hiding messages, mostly so I could pass notes back and forth to classmates during class. It wasn&#8217;t long before I found &#8220;invisible ink&#8221;, which is a form of [...]]]></description>
			<content:encoded><![CDATA[<p>I have been familiar with steganography for a number of years. In fact, back when I was in middle school, I developed a fascination for encryption, and hiding messages, mostly so I could pass notes back and forth to classmates during class. It wasn&#8217;t long before I found &#8220;invisible ink&#8221;, which is a form of steganography. While I&#8217;m certainly no expert on the subject, I decided to have a bit of fun with my email.</p>
<p>I placed a hidden message in my email headers for a bit (I&#8217;ve since stopped, for various reasons). I considered it an &#8220;Easter Egg&#8221; of sorts, waiting for someone to notice. Here is what I placed in the headers:</p>
<pre>Crypto-Challenge: iVBORw0KGgoAAAANSUhEUgAAADwAAAA8AQMAAAAAMksxAAAABlBMVEX
       ///8AAABVwtN+AAAAtklEQVQokXXQMQ6CMBQG4McCiykXMPEKsuEiV2nCBdoLWNgN
       Xqld7MYZeoQSFgbisyZWER//9E1//vcAYhQOvkB0X3AQotBAoZ5lV9hpA63ZxCP5Q
       SiE5N28QpjRxT0rhFzi7BWUlx3LQvMH+x1jx7IEAoer8hVqR4Crhp1fhf9QI976tF
       oAIGlYWTkCCr3I7yTCpTkaDQTqWUhjtFtCNizNgEbbZxMFDnIYrHUEwjPRnywQiHk
       CI/3gDHrryF4AAAAASUVORK5CYII=
Crypto-Hint: image/png</pre>
<p>Quickly, you should identify the &#8220;Crypto-Challenge&#8221; header as base 64-encoded string. The hint says it&#8217;s an image, of type PNG. So, the following Python code should do the trick:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># assuming the 'img_string' variable is the actual base64 string above</span><br />
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'crypto-image.png'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span><br />
f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>img_string.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'base64'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Running that code with the base 64-encoded string above gives the following image:</p>
<p><img src="http://pthree.org/wp-content/uploads/2011/12/crypto-image.png" alt="" title="crypto-image" width="60" height="60" class="aligncenter size-full wp-image-2135" /></p>
<p>Scanning the QR code reveals the text &#8220;42&#8243;, of which most geeks should recognize as &#8220;The Answer to the Ultimate Question of Life, the Universe, and Everything&#8221;.</p>
<p>Of course, steganography isn&#8217;t encryption. It&#8217;s security by obscurity, which isn&#8217;t security, where a message is hidden by obscuring it through some means. Wikipedia has a great article on it at <a href="https://en.wikipedia.org/wiki/Steganography">https://en.wikipedia.org/wiki/Steganography</a>.</p>
<p>What can you do with hidden messages in images (or vice versa, as in the case with my email &#8220;Easter Egg&#8221;)? Well, for one, you can easily get around email attachment restrictions. For example, take a ZIP archive. Perhaps some organization blocks email with .zip attachments. Why not convert the archive to base 64, then convert the result to an image. You might end up with something like this:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> PIL <span style="color: #ff7700;font-weight:bold;">import</span> Image<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">base64</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">math</span><br />
<br />
<span style="color: #808080; font-style: italic;"># function to return max image size</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> get_size<span style="color: black;">&#40;</span>size<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; width <span style="color: #66cc66;">=</span> height <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">math</span>.<span style="color: black;">ceil</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">math</span>.<span style="color: black;">sqrt</span><span style="color: black;">&#40;</span>size/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; diff <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>width * height<span style="color: black;">&#41;</span> * <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> - size<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>width<span style="color: #66cc66;">,</span> height<span style="color: #66cc66;">,</span> diff<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># open our binary non-image file</span><br />
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'archive.zip'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'rb'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># convert the binary to a base64-encoded string</span><br />
enc_bytes <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">base64</span>.<span style="color: black;">b64encode</span><span style="color: black;">&#40;</span>f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># get file size to hold data (square)</span><br />
<span style="color: black;">&#40;</span>w<span style="color: #66cc66;">,</span>h<span style="color: #66cc66;">,</span>d<span style="color: black;">&#41;</span> <span style="color: #66cc66;">=</span> get_size<span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>enc_bytes<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># pad with zeros, if necessary</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> d <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; enc_bytes +<span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\0</span>'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># create our final image</span><br />
img <span style="color: #66cc66;">=</span> Image.<span style="color: black;">frombuffer</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'RGB'</span><span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span>w<span style="color: #66cc66;">,</span>h<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>enc_bytes<span style="color: #66cc66;">,</span><span style="color: #483d8b;">'raw'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'RGB'</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
img.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'image.png'</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Your final image might end up like:</p>
<p><img src="http://pthree.org/wp-content/uploads/2011/12/image.png" alt="" title="image" width="427" height="427" class="aligncenter size-full wp-image-2138" /></p>
<p>In our case, I just created a file from /dev/urandom, zipped it up, and converted to an image. Thus, the reason the data in the image appears so random. More structured files will show actual structure in the final image. Also, notice the string of black at the bottom as a result of our padded zeros to adjust for a square image, without losing data.</p>
<p>Of course, to get back to the archive, you just need to reverse the process of converting the image to a base64 string, then back to the original file. Now, I&#8217;m no Python expert, and I realize there is much more to add to the code, such as &#8220;try/except&#8221; blocks for testing files, writable directories, etc. The point of the code was just to demonstrate an overall algorithm.</p>
<p>Hopefully, this is of some interest to some of my readers. I&#8217;m open to code improvements. Thanks to <a href="https://diablohorn.wordpress.com/2010/12/04/whats-in-a-picture">https://diablohorn.wordpress.com/2010/12/04/whats-in-a-picture</a> for use of the code above.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/12/15/steganography/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google Wants To Track Your Physical Location</title>
		<link>http://pthree.org/2011/11/15/google-wants-to-track-your-physical-location/</link>
		<comments>http://pthree.org/2011/11/15/google-wants-to-track-your-physical-location/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 12:14:17 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2102</guid>
		<description><![CDATA[From http://googleblog.blogspot.com/2011/11/greater-choice-for-wireless-access.html: We&#8217;re introducing a method that lets you opt out of having your wireless access point included in the Google Location Server. To opt out, visit your access point&#8217;s settings and change the wireless network name (or SSID) so that it ends with &#8220;_nomap.&#8221; For example, if your SSID is &#8220;Network,&#8221; you&#8217;d need to [...]]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://googleblog.blogspot.com/2011/11/greater-choice-for-wireless-access.html">http://googleblog.blogspot.com/2011/11/greater-choice-for-wireless-access.html</a>:</p>
<blockquote><p>We&#8217;re introducing a method that lets you opt out of having your wireless access point included in the Google Location Server. To opt out, visit your access point&#8217;s settings and change the wireless network name (or SSID) so that it ends with &#8220;_nomap.&#8221; For example, if your SSID is &#8220;Network,&#8221; you&#8217;d need to change it to &#8220;Network_nomap.&#8221;</p></blockquote>
<p>Great. Just great. Google will now be tracking my wireless access point unless I append &#8220;_nomap&#8221; to the SSID. How many people do you think are going to do this? How many people have even changed their default AP login from &#8220;admin:admin&#8221;? Google is taking advantage of people, and they know it. I hope the backlash is severe, because I find this to be a breach of trust. Whatever happened to &#8220;Do No Evil&#8221;?</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/11/15/google-wants-to-track-your-physical-location/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Use wget(1) To Expand Shortened URLs</title>
		<link>http://pthree.org/2011/10/18/use-wget1-to-expand-shortened-urls/</link>
		<comments>http://pthree.org/2011/10/18/use-wget1-to-expand-shortened-urls/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 14:22:04 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2083</guid>
		<description><![CDATA[I&#8217;m a fan of all things microblogging, but let&#8217;s face it: until URLs become part of the XML, and not part of your character count (which is ridiculous anyway), shortened URLs are going to be a way of life. Unfortunately, those shortened URLs can be problematic. They could host malicious scripts and/or software that could [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a fan of all things microblogging, but let&#8217;s face it: until URLs become part of the XML, and not part of your character count (which is ridiculous anyway), shortened URLs are going to be a way of life. Unfortunately, those shortened URLs can be problematic. They could host malicious scripts and/or software that could infect your browser and/or system. They could lead you to an inappropriate site, or just something you don&#8217;t want to see. And because these URLs are a part of our microblogging lives, they&#8217;ve also become a part of our email, SMS, IM, IRC, lives as well as other online aspects.</p>
<p>So, the question is: do you trust the short URL? Well, I&#8217;ve generally gotten into the habit of asking people to expand the shortened url for me if on IRC, email or IM, and it&#8217;s worked just fine. But, I got curious if there was a way to do it automagically, and thankfully, you can use wget(1) for this very purpose. Here&#8217;s a &#8220;quick and dirty&#8221; approach to expanding shortened URLs (emphasis mine):</p>
<pre>$ wget --max-redirect=0 -O - http://t.co/LDWqmtDM
--2011-10-18 07:59:53--  http://t.co/LDWqmtDM
Resolving t.co (t.co)... 199.59.148.12
Connecting to t.co (t.co)|199.59.148.12|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
<b>Location: http://is.gd/jAdSZ3 [following]</b>
0 redirections exceeded.</pre>
<p>So, in this case &#8220;http://t.co/LDWqmtDM&#8221; is pointing to &#8220;http://is.gd/jAdSZ3&#8243;, another shortened URL (thank you Twitter for shortening what is already short (other services are doing this too, and it&#8217;s annoying- I&#8217;m looking at you StatusNet)). So, let&#8217;s increase our &#8220;&#8211;max-redirect&#8221; (again, emphasis mine):</p>
<pre>$ wget --max-redirect=1 -O - http://t.co/LDWqmtDM
--2011-10-18 08:02:12--  http://t.co/LDWqmtDM
Resolving t.co (t.co)... 199.59.148.12
Connecting to t.co (t.co)|199.59.148.12|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
<b>Location: http://is.gd/jAdSZ3 [following]</b>
--2011-10-18 08:02:13--  http://is.gd/jAdSZ3
Resolving is.gd (is.gd)... 89.200.143.50
Connecting to is.gd (is.gd)|89.200.143.50|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
<b>Location: https://wiki.ubuntu.com/UbuntuOpenWeek [following]</b>
1 redirections exceeded.</pre>
<p>So, in this case, the link finally points to <a href="https://wiki.ubuntu.com/UbuntuOpenWeek">https://wiki.ubuntu.com/UbuntuOpenWeek</a>. I&#8217;m familiar enough with the Ubuntu Wiki, that I know I should be safe visiting the initial shortened URL. If you want to add this to a script or shell function, then you can get a bit more fancy:</p>
<pre>$ expandurl() { wget -O - --max-redirect=$2 $1 2>&#038;1 | grep ^Location; }
$ expandurl http://t.co/LDWqmtDM 1
Location: http://is.gd/jAdSZ3 [following]
Location: https://wiki.ubuntu.com/UbuntuOpenWeek [following]</pre>
<p>In this case, our &#8220;expandurl()&#8221; function takes two arguments: the first being the URL you wish to expand, and the second being the max redirects. You&#8217;ll notice further that I added &#8220;-0 -&#8221; to print to STDERR. This is just in case you give too many redirects, it will print the content of the page&#8217;s HTML to the terminal, rather than saving to a file. Because you&#8217;re grepping for &#8220;^Location&#8221;, and sending the HTML to your terminal anyway, technically you could get rid of the &#8220;&#8211;max-redirects&#8221; altogether. But, keeping it in play does seriously increase the time it takes to get the locations. Whatever works for you.</p>
<p><strong>UPDATE (Oct 18, 2011):</strong> After some comments have come in on the post, and some discussion on IRC, there is a better way to handle this. According to the wget(1) manpage, &#8220;-S&#8221; or &#8220;&#8211;server-response&#8221; will print the headers and responses printed by the FTP/HTTP servers. So, here&#8217;s the updated function that you might find to be less chatty, and faster to execute as well:</p>
<pre>$ expandurl() { wget -S $1 2>&#038;1 | grep ^Location; }
$ expandurl http://t.co/LDWqmtDM
Location: http://is.gd/jAdSZ3 [following]
Location: https://wiki.ubuntu.com/UbuntuOpenWeek [following]</pre>
<p>Perfect.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/10/18/use-wget1-to-expand-shortened-urls/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>PGP/MIME Versus S/MIME</title>
		<link>http://pthree.org/2011/09/17/pgpmime-versus-smime/</link>
		<comments>http://pthree.org/2011/09/17/pgpmime-versus-smime/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 13:41:24 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=2039</guid>
		<description><![CDATA[I&#8217;m going to try to keep this post short (many of my regular readers will know how long winded I can be). However, with my recent post of setting up Mutt to support both PGP/MIME and S/MIME, based on the account I&#8217;m using, I figure a followup post on their similarities and differences might be [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to try to keep this post short (many of my regular readers will know how long winded I can be). However, with <a href="http://pthree.org/2011/09/15/setting-up-mutt-with-smime-and-pgpmime/">my recent post of setting up Mutt to support both PGP/MIME and S/MIME</a>, based on the account I&#8217;m using, I figure a followup post on their similarities and differences might be in order. So, here it goes:</p>
<p><strong>PGP/MIME</strong></p>
<ol>
<li>Uses the OpenPGP RFCs and standards.</li>
<li>The &#8220;signature.asc&#8221; detached signature is in plain text.</li>
<li>Flexibility in algorithm choice for encryption, signing and compression.</li>
<li>Relies on a distributed trust model.</li>
<li>Not as widely deployed in MUAs as S/MIME.</li>
<li>Public key must be distributed separately from the signature.</li>
<li>Trivial to integrate with webmail providers.</li>
<li>Can only be used with signing documents.</li>
<li>An expiration date does not need to be set on the public key.</li>
<li>Free.</li>
</ol>
<p><strong>S/MIME</strong></p>
<ol>
<li>Based on a number of RFCs and standards.</li>
<li>The &#8220;smime.p7s&#8221; detached signature is in a binary format.</li>
<li>Generally, the Certificate Authority (CA) chooses the algorithm and key size.</li>
<li>Relies on a centralized trust model.</li>
<li>More widely deployed than PGP/MIME</li>
<li>Public certificate distributed in each detached signature.</li>
<li>Difficult to integrate with webmail providers.</li>
<li>Can be used for both signatures and encryption.</li>
<li>Generally, the public certificate expires once per year.</li>
<li>Some CAs provide certs free for personal use, but most if not all CAs charge for professional use. As low as $20 per year, depending on the CA.</li>
</ol>
<p>This isn&#8217;t an exhaustive list, but it&#8217;s pretty good. I&#8217;ve tried to keep any bias out of the list, and just mention the facts. Really, I get a kick out of using both, so meh. But, if I were forced to choose, I would choose the distributed OpenPGP model for signatures.</p>
<p>The biggest reason for this choice actually doesn&#8217;t even use PGP/MIME, thus the reason it&#8217;s not listed. That reason is I can set preferences in my key as to what must be used when encrypting documents to me. Thus, I can force you to send me a 2048 RSA encrypted document. With S/MIME, which can handle encryption, no such preferences exist, which means that there is nothing from stopping you sending me a 40-bit RSA encrypted document. I think you can see the security problem here.</p>
<p>Another problem I see with S/MIME is the reliance on a centralized authority. Essentially, you can trust I signed my mail with S/MIME, because my certificate is signed by DigiNotar and <a href="http://en.wikipedia.org/wiki/DigiNotar#Issuance_of_fraudulent_certificates">we all trust DigiNotar</a>. Oh, wait. While the issuance of fraudulent public keys is a reality, the probability is much less likely, due to the distributed Web of Trust. Of course, this means there is a fair amount of homework that you must do in verifying that the key is legit, and that confidential information can be trusted with that key, but it is possible to make such assumptions.</p>
<p>Lastly, S/MIME is rather trivial to maintain. You pay a CA for a certificate, and you install the certificate in your mail client, and you&#8217;re ready to go. OpenPGP and PGP/MIME isn&#8217;t so trivial. You must generate your own keys, generally with PGP or GnuPG, and know the difference between your private and public keys. Then, you must install a plugin or extension into your MUA, which all don&#8217;t support, and configure that plugin to work with your keys. Then you must distribute your public key to friends and family, as well as keyservers, so others can grab a copy. But they can&#8217;t trust your data, until they meet up with you and do a keysigning, which means you must then redistribute the public key after their signature has been applied. In both cases, however, you can&#8217;t encrypt data to people unless you have their public key or certificate.</p>
<p>Both are internet standards, and both are fairly widely deployed. Unfortunately, there is work on your end that must be done on setting it up, and maintaining it, whether it&#8217;s a yearly cost or attending keysigning parties. As a result, it&#8217;s not as widely used in practice as much as it could be. I&#8217;ve made it a personal philosophy that I won&#8217;t send mail unless it&#8217;s cryptographically signed. This is true both personally and professionally. I would love it if my family and friends took the steps necessary to verify the signature, but it just isn&#8217;t going to happen. End-to-end security with email seems to have just too many speed bumps that people are willing to handle. That won&#8217;t stop me though.</p>
<p>Anyway, I hope this was at least somewhat informative.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/09/17/pgpmime-versus-smime/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>OpenSSH Best Practices</title>
		<link>http://pthree.org/2011/07/22/openssh-best-practice/</link>
		<comments>http://pthree.org/2011/07/22/openssh-best-practice/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 07:46:54 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1930</guid>
		<description><![CDATA[This post comes from Matt Taggart, who put together a document about the best practices for using OpenSSH. A lot of the points brought up in that document rang the bells of common sense, and are so good, it&#8217;s worth blogging about in hopes that the points mentioned therein reach as many as possible. I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>This post comes from Matt Taggart, who put together a document about the <a href="http://lackof.org/taggart/hacking/ssh/">best practices for using OpenSSH</a>. A lot of the points brought up in that document rang the bells of common sense, and are so good, it&#8217;s worth blogging about in hopes that the points mentioned therein reach as many as possible. I&#8217;ve also added a couple extra points that I&#8217;ve learned with my experience using OpenSSH.</p>
<p>These are best practices from the client perspective, not the server. Many of these points you will have already been familiar with, but some of them not as much. If you sit down and think about what you are doing as a client when you SSH to a server, some of the implications mentioned here make sense.</p>
<p>Lastly, security is a big topic, and not something that can be flipped on and off with a switch. Security always starts with the user. Unfortunately, increasing your security could mean making usability more of a pain in the rear. However, as an OpenSSH client, I hope the techniques mentioned here won&#8217;t decrease your usability too bad, while greatly increasing your overall OpenSSH security. With that said, let&#8217;s get started.</p>
<p><strong>0. Use ECC first, then RSA, then DSA with maximum bit strength.</strong><br />
When generating your OpenSSH keys, you should be aware of the cryptographic algorithms of the OpenSSH server that you are accessing, and what you can and cannot use. As of OpenSSH version 5.7, <a href="http://pthree.org/2011/02/17/elliptic-curve-cryptography-in-openssh/">elliptic curve cryptography is a supported algorithm</a>. It is proving to be a very secure, robust and light crypto algorithm, but it also must be supported by both the client and the remote server. This means that both the client and the server must be relatively new installations of OpenSSH- something that RHEL 6 and earlier, Debian GNU/Linux Stable 6 and earlier, Ubuntu 10.10 and earlier, and likely many other stable releases from other GNU/Linux operating systems, do not support. When you can, use elliptic curve cryptography for your SSH keys.</p>
<p>If ECC is not available on either your client or server, then you should choose RSA as your key&#8217;s crypto. DSA suffers from a weakness, where if the host does not have a sufficiently strong pseudorandom number generator (PRNG), then the &#8220;random k&#8221; could become exposed from the public key, allowing the attacker to build the private key from the public. The PRNG supplied by GNU/Linux (the device file &#8220;/dev/urandom&#8221;) is sufficiently strong, providing good random data from entropy pools- thus, GNU/Linux generally doesn&#8217;t suffer from this problem. Other operating systems could.</p>
<p>A great demonstration of DSA&#8217;s weakness can be found in <a href="http://rdist.root.org/2010/11/19/dsa-requirements-for-random-k-value/">this excellent blog post</a>, where the author demonstrates how trivial it is to build the private key when the &#8220;random k value&#8221; is known. Fortunately, RSA does not suffer from this weakness, and also allows you to build larger keys than DSA.</p>
<p>If neither ECC nor RSA is supported by the client nor server, as is the case with some archaic proprietary SSH implementations, then DSA is your only option. Unfortunately, it is also the default for OpenSSH when generating a key. So, you should always get into the habit of passing the &#8220;-t [type]&#8221; switch when generating your keys.</p>
<p>In all 3 cases, where possible, you should choose the maximum bit strength that the algorithm allows. This will put a bit of strain on the client&#8217;s CPU, but it will also give you the greatest strength when authenticating on the wire. When generating your key, use the &#8220;-b [size]&#8221; switch to specify the bit strength.</p>
<p><strong>1. Use SSH keys and make your servers require them.</strong><br />
There are three reasons why you would want to use SSH keys:</p>
<ol>
<li>SSH keys with a passphrase provide two-factor authentication.</li>
<li>SSH passwords can be read in plain text on the remote server.</li>
<li>SSH keys aren&#8217;t subject to brute force dictionary attacks, like passwords.</li>
</ol>
<p>Let&#8217;s cover each in detail. First, two-factor authentication. SSH keys use public key cryptography. You are given a private and public key when generated. During generation, you are asked to provide a passphrase for the private key. DO NOT GIVE IT AN EMPTY PASSPHRASE! By providing a passphrase to your key, you have enabled the two-factor authentication- something you have (the key) and something you know (the passphrase). Using SSH keys can be troublesome, however. As a result, take advantage of the SSH agent for your system to cache the passphrase locally on your client. This will increase your usability by only entering your key passphrase once, and using the agent to login to other servers without providing the key passphrase again.</p>
<p>Second is reading the user password in plain text on the remote SSH server. You may not think this is possible, as everything in OpenSSH is encrypted, right? Wrong. The two Achilles Heel&#8217;s in the connection are the client and servers themselves, where the decryption is taking place. Other users, specifically those who have superuser access, can exploit this. To demonstrate this, make a connection to a server that you have superuser access on. Then, from the client initiate a connection that would require your server password, but don&#8217;t supply it. Go back to the server, and find the process of the connection, and run an strace on the PID. Go back to the client, and type in your password. Watch, very likely in horror, the password be displayed on your console.</p>
<p><a href="http://blog.josephhall.com/2009/12/fun-with-sshd-and-strace.html">Here is an excellent writeup</a> by Joseph Hall on this very issue. The problem lies in whether or not you trust those who have superuser access on the server. You should only trust them enough to do their job on the server, and nothing more. Just because they have superuser access on the server, doesn&#8217;t mean they can be trusted with your banking account information. Because people use the same passwords over and over across multiple accounts, it&#8217;s likely that the password sniffed out of the connection is the same password for their email account. Or bank.</p>
<p>Third, as should be obvious, SSH keys aren&#8217;t subject to brute force dictionary attacks like passwords are. If you control the SSH server, and require that SSH keys are the mode of authentication, then brute force attacks will be in vain, regardless how long they try. If you have a publicly facing SSH server, you&#8217;re likely aware of how hard your server gets hit from attackers all over the world. By forcing key authentication, all those attacks are in vain.</p>
<p><strong>2. Don&#8217;t use a blank passphrase on your keys.</strong><br />
This should come as no surprise, but needs to be mentioned. Your SSH keys are something that should be guarded carefully, with sufficient paranoia. If for any reason, your SSH client is compromised, your SSH keys are a way in to the remote servers that you have access to. If your keys are not protected by passphrases, then after scouring your shell history, or SSH config for hosts to connect to, they&#8217;re in the SSH server with little effort. You must protect your keys with strong passphrases!</p>
<p>Now, I understand that there are some like me, who use SSH as the connection for nightly local backups, at which point the client will be asked for the passphrase of the SSH key. Because you wish this to be an automated process, and likely when you&#8217;re in bed, you won&#8217;t be available all the time to provide the credentials. So, you create an SSH keypair that is not passphrase protected. In such a scenario, here is what I would do:</p>
<ol>
<li>Only install this key on the backup SSH server, and no where else.</li>
<li>Do not install this key into an account that has superuser access.</li>
<li>Do not install this key into the superuser account.</li>
<li>On the backup server, change the key entry in the authorized_keys file to only allow connections from that client using that key (documented how below).</li>
</ol>
<p>The first, second and third points are easy enough to configure, but how do you configure the fourth point, and is it even possible? When you copy the key to the authorized_keys file on the SSH server, it could look something like this:</p>
<pre>ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzoblHIUARNP5Kq12QwUqxB6T7m8TWti4LIFcvOCa...</pre>
<p>Change the beginning of that entry to this:</p>
<pre>from="10.19.84.10",command="/home/user/bin/validate.sh" ssh-rsa AAAAB3NzaC1y...</pre>
<p>This tells the server that the only connections allowed to use this key can come from &#8220;10.19.84.10&#8243;, and when the connection is made, a local script is ran called &#8220;validate.sh&#8221;. Here are the contents of that script for me:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/bin/sh</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SSH_ORIGINAL_COMMAND</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #000000; font-weight: bold;">&amp;*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\;<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #000000; font-weight: bold;">&lt;*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #000000; font-weight: bold;">`*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #000000; font-weight: bold;">|*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; rsync\ --server<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007800;">$SSH_ORIGINAL_COMMAND</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Rejected&quot;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
<span style="color: #000000; font-weight: bold;">esac</span></div></td></tr></tbody></table></div>
<p>Make sure the script is executable by the user account on the SSH server, and test it before committing to it as part of your backup policy. If the client host is behind a dynamic IP address, or some other variable that prevents it from having a static address, you can remove the &#8220;from=&#8221; part, but leave the &#8220;command=&#8221; part. The goal is to minimize damage that can be done with that key.</p>
<p>Again, this is all if you need to perform an automated backup with SSH keys, where a passphrase cannot be performed. In almost every other case, your SSH key should be protected by a good, strong, <a href="http://pthree.org/2011/03/07/strong-passwords-need-entropy/">loaded with entropy</a> passphrase. Using one from a <a href="http://pthree.org/2010/09/21/password-cards/">passwordcard</a> is probably best.</p>
<p><strong>3. Use a separate key for every client you SSH from.</strong><br />
I admit that when I first started using SSH, this didn&#8217;t make much sense to me. The amount of keys that I generated was a lot, and managing them became somewhat of a pain. Then, when becoming system administrator of a large organization, and controlling upwards of 300 servers, managing that many keys become immensely intense.</p>
<p>I soon came to the realization that it wasn&#8217;t that big of a deal. It is trivial to copy the key to the remote host (this can be done with the &#8220;<a href="http://linux.die.net/man/1/ssh-copy-id">ssh-copy-id(1)</a>&#8221; command). Further, for work SSH keys, while I am in charge of managing those keys, I should only worry about work keys at work, and home keys at home. In other words, separate the management of the keys.</p>
<p>But the point of this is to NOT copy the same client key to multiple clients. Think about it. By copying the key around to multiple clients, this means that the key is on every server you ever access from those clients, even if some of the other clients cannot access that server directly. Thus, if a client is compromised, and the key is stolen, it&#8217;s difficult to know which client was compromised, and all servers that have that key in their authorized_keys file, are subject to compromise. If you have a different key for each client, then those keys are only on the servers that the client has direct access to, and should a client become compromised, you know which servers to saefguard, and damage is minimal.</p>
<p><strong>4. Limit the number of clients you SSH from.</strong><br />
If an attacker can compromise your client, then they can get access to your SSH keys, as they are stored on the filesystem. Further, they may be able to install a keylogger to log passwords and passphrases, including those for your key. Once this information is gained, then all the accounts on the servers the key is installed on are now compromised as well. By limiting the number of clients you SSH from, you minimize the exposure of SSH servers to the attacker.</p>
<p><strong>5. Don&#8217;t &#8220;chain&#8221; or &#8220;loop&#8221; logins, but do &#8220;star&#8221;.</strong></p>
<p><img alt="" src="http://lackof.org/taggart/hacking/ssh/ssh.png" title="SSH Scenarios" class="alignnone" width="961" height="262" /></p>
<p>The point relates to the one above it, namely limiting the number of hosts you SSH FROM. There are a few scenarios on how you can create SSH sessions:</p>
<ul>
<li>Chain: As a client, you make a connection with an SSH server. Then, from that server, you make another connection to a different SSH server. Once, twice, three times or more, you&#8217;ve created a chain of connections from the client to the final host.</li>
<li>Loop: As a client, you make a connection with an SSH server. Then, from that server, you make a connection back to the client you started from, thus creating a loop with your connections.</li>
<li>Star: As a client, one connection is made to an SSH server. If another connection is needed to a different SSH server, this is made from the client. For each connection, the original client makes it.</li>
</ul>
<p>The reasons why this is a &#8220;best practice&#8221; might not be obvious. Let&#8217;s start first with chaining connections. If one client is compromised in the chain, the other clients in the chain might possibly be compromised using the same method. Thus, all connections in the chain could become compromised. And a loop is nothing more than a specific instance of a chain.</p>
<p>Of course, this isn&#8217;t always possible. Maybe a chain is the only way to get to an SSH server on a private VLAN or behind a DMZ. These connections might be necessary (typically called &#8220;jump hosts&#8221;), but they should be used with caution, and as little as possible. When you are done with your task, rather than idle the SSH connection, terminate it to minimize exposure, should an attack occur.</p>
<p>When using a jump host, install netcat(1) on the jump host and use the ProxyCommand configuration paramater. Something like this would be sufficient:</p>
<pre>Host inaccessiblehost1 inaccessiblehost2
   ProxyCommand ssh accessiblehost nc -q0 %h %p</pre>
<p>With star connections, you minimize the risk of compromise with each of your connections, but security is maximized, even if extra work is required on your end. For example, if you wish to transfer data from one SSH server to another, this may mean bringing the data to the client, then sending it to the destination server.</p>
<pre></pre>
<p><strong>6. Consider disabling the SSH server on the client you are connecting from.</strong><br />
This rule shouldn&#8217;t apply only to the SSH server, but to any daemon you have running on your machine. If you don&#8217;t need a service running, then turn it off. By doing so, you minimize the attack vector and greatly increase your security. OpenBSD prides itself in having only two remote holes in the default install in a heck of a long time, but then it also doesn&#8217;t have any services running on a default install either.</p>
<p>So, for SSH, because you followed rule #5, and you aren&#8217;t doing &#8220;chain&#8221; or &#8220;loop&#8221; connections from your client, then this means that you&#8217;re not connecting to your own machine that you started your initial connection from. I understand that this isn&#8217;t always possible. I have 300+ SSH servers at work, and I can&#8217;t possible turn off the SSH server on a host, just because I&#8217;m connecting from it. But then, do I need an SSH server on my virtual laptop? Not likely, and if there are things I need, I can turn it on, do my work, then turn it off.</p>
<p><strong>7. Don&#8217;t ignore SSH host key warnings.</strong><br />
When you install an SSH server for the first time, it creates a server public and private keypair. This set of keys is what is used for the encryption and decryption between your client and the SSH server. Thus, all traffic that you are sending to that server, is done because you trust that the SSH server key presented to you, is indeed the key of the server itself. So, what happens when you connect a different time, and your client warns you that the public SSH server key has changed? Should you trust the connection?</p>
<p>Depends. Usually, it&#8217;s due to the fact that you either reinstalled the SSH server or reinstalled the operating system. In this case, you can move forward, so long as you know that the key presented is the new key from the server. However, someone could setup a proxy SSH server, for the intent of gaining system passwords. Your client will warn you the key is different, and you should pay attention to the warning.</p>
<p>So, in your SSH client config, you generally should not set the following:</p>
<pre>Host *
    StrictHostKeyChecking no</pre>
<p>Default is &#8220;yes&#8221;, and it should stay yes in your config. OpenSSH is verbose enough for your benefit. Try to take advantage of it, rather than silence it, or ignore it. After all, it&#8217;s your data.</p>
<p><strong>8. Be wary of using X11 forwarding.</strong><br />
While taking advantage of the ability to run remote X applications locally on your client is nice, it has some very grave drawbacks. For example, it&#8217;s common for people to launch a remote browser, such as Firefox. What isn&#8217;t realized, is that you&#8217;re providing usernames and passwords through the browser, which could be caught on the remote machine from which the app is running (taking advantage of X events, for example).</p>
<p>There is a time and a place for X11 forwarding, and I have benefited by it, but generally, it&#8217;s not needed. Set the following in your SSH client config, and only enable it when needed:</p>
<pre>Host *
    ForwardX11 no</pre>
<p><strong>9. Don&#8217;t use agent forwarding.</strong><br />
As with X11 forwarding, you are giving ultimate trust to the remote host when forwarding your local agent. If that connection makes a connection to an account with superuser privileges, then a user on the remote SSH server could hijack your agent by connecting to the socket the SSH server creates.</p>
<p>Also, on the client initiating the connection, the superuser must be trusted, which isn&#8217;t always the case. The local superuser can access the agent socket on the client, and attack. Thus, it&#8217;s generally not a good idea to enable agent forwarding. Thus, as it is by default, the following should be sent in your client SSH config:</p>
<pre>Host *
    ForwardAgent no</pre>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/07/22/openssh-best-practice/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Convert Text To Base-64 By Hand</title>
		<link>http://pthree.org/2011/04/06/convert-text-to-base-64-by-hand/</link>
		<comments>http://pthree.org/2011/04/06/convert-text-to-base-64-by-hand/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 05:11:20 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1862</guid>
		<description><![CDATA[When I was a kid, I had this fascination with cryptography. I learned and used, as most kids to, the Caesar cipher first (using my trusty Captain Crunch Decoder Ring), then later learned and used the Affine cipher. It was great for passing notes in class when I was in elementary and secondary education. I [...]]]></description>
			<content:encoded><![CDATA[<p>When I was a kid, I had this fascination with cryptography. I learned and used, as most kids to, the Caesar cipher first (using my trusty Captain Crunch Decoder Ring), then later learned and used the Affine cipher. It was great for passing notes in class when I was in elementary and secondary education. I even learned the ancient runes, and used those quite a bit too.</p>
<p>Since then, I&#8217;ve been fascinated by hand cipher techniques, and I&#8217;ve learned a few historical ones over the years. I&#8217;ve even invented my own hand cipher, even though I doubt it would show any form of cryptanalytic strength. While I don&#8217;t do anything with hand ciphers practically, I still consider it a fun skill to have, whether or not it actually proves to be useful (when I was a Boy Scout, I always wanted to learn Morse Code, so I could tap out answers to a quiz or test in class to a fiend, and back to me without anyone knowing. How cool would that be?!).</p>
<p>While I know base-64 is not considered a cipher algorithm, I thought to myself that I don&#8217;t know how to convert a string of ASCII text to base-64 by hand. So, I figured I might as well learn. It could be an interesting skill to add to my own hand cipher, and could even prove to be useful around the house. So, if you&#8217;re curious, here we go.</p>
<p><strong>STEP ONE: Know the ASCII code chart</strong></p>
<p>I would recommend memorizing or printing out (and stuffing in your wallet) this chart here: <a href="http://en.wikipedia.org/wiki/File:ASCII_Code_Chart-Quick_ref_card.png">http://en.wikipedia.org/wiki/File:ASCII_Code_Chart-Quick_ref_card.png</a>. Reason being, is you need to covert the ASCII text to numerical binary. The chart linked to gives you the table on how to do it.</p>
<p>Really, you can use any standard ASCII chart that provides you with the decimal, octal or hexadecimal values of the character. So long as you can convert it to binary, that&#8217;s all that matters. I like the linked chart above, because it gives it to me out the gate, which is one less conversion to worry about.</p>
<p><strong>STEP TWO: Convert your ASCII string to numerical binary</strong></p>
<p>This is the tedious part. It&#8217;s going to take you some time to write down every character in 8-bit binary. I need to stress that you need to write down the FULL 8 BITS, even though the card linked to only gives you 7. So, the 8th bit will always be zero when writing down the full binary word. Here&#8217;s a rundown of how you would read the card:</p>
<ol>
<li>Find the character you wish to convert</li>
<li>Write down 0 + the first three binary bits on the top</li>
<li>Write down the last four binary bits for that letter on the left</li>
</ol>
<p>So, for example, the text &#8220;green&#8221; would be &#8220;01100111 01110010 01100101 01100101 01101110&#8243;. Notice that each binary word is 8 bits, each with leading zeros. This should be the case for EVERY character you write down. Further, the space between letters is NOT ignored. It has the binary value of &#8220;00100000&#8243; (&#8220;SP&#8221; in the chart).</p>
<p><strong>STEP THREE: Pad at the end as necessary with zeros</strong></p>
<p>The total number of bits should be divisible by 6. If it is not, add the necessary zeros at the end until it is. So, for our example of &#8220;green&#8221;, we have a total of 40 bits, which means we need to add two more zeros to make it divisible by 6 (42 divided by 6 is 7). It&#8217;s important that you stop at the first multiple of 6, which means that you should never be adding more than 4 zeros. In fact, you will either be adding two zeros, four zeros, or none at all.</p>
<p>So, for &#8220;green&#8221; with padded zeros at the end, our binary string becomes: &#8220;01100111 01110010 01100101 01100101 01101110 00&#8243;</p>
<p><strong>STEP FOUR: Divide your binary string into words of 6 bits</strong></p>
<p>Because our binary string is now divisible by six, we want to make 6-bit words using the same string. So, for &#8220;green&#8221;, I should end up with 7 total words (because I have 42 bits total in the string). As a result, &#8220;01100111 01110010 01100101 01100101 01101110 00&#8243; becomes &#8220;011001 110111 001001 100101 011001 010110 111000&#8243;</p>
<p><strong>STEP FIVE: Convert your 6-bit words to decimal</strong></p>
<p>Now we need to covert the newly created binary words into decimal. You need to know your binary to pull this off. Thankfully, this isn&#8217;t too terribly difficult- you just need to know your powers of 2. So, our string of &#8220;011001 110111 001001 100101 011001 010110 111000&#8243; becomes &#8220;25 55 9 37 25 22 56&#8243;.</p>
<p><strong>STEP SIX: Convert decimal to ASCII</strong></p>
<p>Now, we need to covert our newly calculated decimal numbers to ASCII, and we&#8217;ll almost be finished. For this, we&#8217;re going to use a different chart than what we started with. We need a chart that will correspond to our values, starting at 0 and ending on 63 (64 possible values, thus the reason it&#8217;s called &#8220;base-64&#8243;).</p>
<ol>
<li>If the value is between 0 and 25, then the character is uppercase &#8220;A-Z&#8221; respectfully.</li>
<li>If the value is between 26 and 51, then the character is lowercase &#8220;a-z&#8221; respectfully.</li>
<li>If the value is between 52 and 61, then the character is the numbers &#8220;0-9&#8243; respectfully.</li>
<li>If the value is 62 or 63, then the character is &#8220;+&#8221; and &#8220;/&#8221; respectfully.</li>
</ol>
<p>If that was confusing to you, see the table at <a href="http://en.wikipedia.org/wiki/Base64#Examples">http://en.wikipedia.org/wiki/Base64#Examples</a>.</p>
<p>So, for our string of numbers &#8220;25 55 9 37 25 22 56&#8243;, which came from the text &#8220;green&#8221;, we see the following come out: &#8220;Z3JlZW4&#8243;.</p>
<p><strong>STEP SEVEN: Pad the string with &#8220;=&#8221; as necessary</strong></p>
<p>The last step in your conversion is to pad the string with &#8220;=&#8221; as necessary, so the total number of your characters is divisible by four. Our base-64 string has only 7 characters, so we must add a &#8220;=&#8221; at the end to bring the total to 8 characters, which is indeed divisible by four. Thus, we would end up with &#8220;Z3JlZW4=&#8221; as the final result for &#8220;green&#8221;.</p>
<p><strong>QUICK EXAMPLE: &#8220;Attack at dawn!&#8221;</strong></p>
<ol>
<li>Attack at dawn!</li>
<li>01000001 01110100 01110100 01100001 01100011 01101011 00100000 01100001 01110100 00100000 01100100 01100001 01110111 01101110 00100001</li>
<li>010000 010111 010001 110100 011000 010110 001101 101011 001000 000110 000101 110100 001000 000110 010001 100001 011101 110110 111000 100001</li>
<li>No zero padding necessary</li>
<li>16 23 17 52 24 22 13 43 8 6 5 52 8 6 17 33 29 54 56 33</li>
<li>QXR0YWNrIGF0IGRhd24h</li>
<li>No &#8220;=&#8221; padding necessary</li>
</ol>
<p><strong>NOTE:</strong></p>
<p>The base 64 utilities that ship with GNU Coreutils and OpenSSL use a different padding at the end of the encoded string than just equal signs. I haven&#8217;t parsed the code yet, so I don&#8217;t know why this is, but from what I&#8217;m reading online, the standard is to use just &#8220;=&#8221;, unless I&#8217;m missing something. If anyone knows why &#8220;K&#8221;, &#8220;o=&#8221; and others show up, I&#8217;m all ears. Thanks.</p>
<p><strong>CONCLUSION:</strong></p>
<p>Encoding text to base-64 certainly doesn&#8217;t really yield any cryptographic strength, and there exist utilities for doing it on the computer. So, why bother learning it by hand? As stated earlier, it&#8217;s a fun skill to have around the house. Combine it with other hand ciphers that you might already know, and you could have a decent algorithm on your hands (pun intended). Heck, let&#8217;s see your English teacher decrypt your notes now!</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/04/06/convert-text-to-base-64-by-hand/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Verifying Hashcash Tokens With Mutt</title>
		<link>http://pthree.org/2011/03/29/verifying-hashcash-tokens-with-mutt/</link>
		<comments>http://pthree.org/2011/03/29/verifying-hashcash-tokens-with-mutt/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 03:32:35 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1842</guid>
		<description><![CDATA[Just five days ago, I blogged about minting Hashcash tokens in Mutt using a Python script (make sure you check that page for any updates to the source if you&#8217;re using it). Well today, I finished writing my verification script. It takes some additional changes to your ~/.muttrc, which I&#8217;ll outline here, and it requires [...]]]></description>
			<content:encoded><![CDATA[<p>Just five days ago, I blogged about <a href="http://pthree.org/2011/03/24/hashcash-and-mutt/">minting Hashcash tokens in Mutt</a> using a Python script (make sure you check that page for any updates to the source if you&#8217;re using it). Well today, I finished writing my verification script. It takes some additional changes to your ~/.muttrc, which I&#8217;ll outline here, and it requires the installation of a Python script. Of course, as previous, I&#8217;m assuming that you&#8217;re running at least Python 2.5 and the latest version of <a href="http://hashcash.org">Hashcash</a>. With that, let&#8217;s get busy.</p>
<p>First, the necessary changes to your &#8220;~/.muttrc&#8221; config. The script relies on the &#8220;X-Hashcash:&#8221; header (as well as the &#8220;Hashcash:&#8221; header- I guess there was some discrepancy or something about X-headers being deprecated, or something) not being weeded out. It must be displayed if present. This way, the script can actually see the token in the header, and process the logic of checking if it&#8217;s valid. If you hid the hashcash headers, then the script won&#8217;t execute, and as a result, won&#8217;t add anything to the token database. We use the $display_filter variable to execute the Python script, and show the results to the pager. Here&#8217;s the changes you will need to make:</p>
<pre># file: ~/.muttrc
ignore *                                    # draconian header weed - recommended
unignore from date subject to cc user-agent # standard headers unignored - recommended
unignore x-hashcash hashcash                # required</pre>
<p>You will also need to set the $display_filter variable. I like having my theme consistent, so I&#8217;ve also added color to my theme to show the Hashcash verification at the top of the mail:</p>
<pre># file: ~/.muttrc
set display_filter="/path/to/verify_hashcash.py"    # required
color body brightyellow default "^\\[--.*Hashcash*" # recommended</pre>
<p>Now with that set, all we need to do is install the Python script, and we&#8217;re ready to go. When looking over the code, you&#8217;ll notice that it&#8217;s creating a database of spent tokens. I&#8217;ve placed the database in ~/.mutt/, seeing as though I only have Mutt working with Hashcash at the moment (and it&#8217;s really the only MUA I use these days). If you have something else that uses Hashcash tokens, in an already existing database, you may want to make the necessary modifications to the Python script, so it&#8217;s pointing to the right file. Also, we&#8217;re only interested in keeping track of tokens minted for us personally, not all tokens we can find in the headers. Lastly, this Python script is only working for one email address. If you have multiple emails, as I do, you&#8217;ll have to either use a primary email to verify the tokens against, or modify the Python script to support checking tokens under multiple accounts.</p>
<p>With that said, here&#8217;s the script:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span><br />
<span style="color: #808080; font-style: italic;"># Licensed under the public domain</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">rfc822</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">StringIO</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Change the DB path in COMMAND as needed, and change your email address</span><br />
COMMAND<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;hashcash -cdb '%s' -r '%s' -f /home/user/.mutt/hashcash.db '%s'&quot;</span><br />
EMAILADDR<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;foo@bar.com&quot;</span><br />
<br />
tokens <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
token_status <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># converting a list to a file-type object for parsing rfc822 headers</span><br />
original <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdin</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
emailmsg <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">StringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>original<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
message <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">rfc822</span>.<span style="color: black;">Message</span><span style="color: black;">&#40;</span>emailmsg<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># check for the presence of &quot;X-Hashcash&quot; and &quot;Hashcash&quot; headers</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> message.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;X-Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> hc_list <span style="color: #ff7700;font-weight:bold;">in</span> message.<span style="color: black;">getheaders</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;X-Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; tokens.<span style="color: black;">append</span><span style="color: black;">&#40;</span>hc_list<span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> message.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> hc_list <span style="color: #ff7700;font-weight:bold;">in</span> message.<span style="color: black;">getheaders</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; tokens.<span style="color: black;">append</span><span style="color: black;">&#40;</span>hc_list<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># check each token</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> tokens:<br />
&nbsp; &nbsp; token_status.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[-- Begin Hashcash output --]&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> hc_token <span style="color: #ff7700;font-weight:bold;">in</span> tokens:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> hc_token.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">==</span> EMAILADDR:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hc_bits <span style="color: #66cc66;">=</span> hc_token.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hc_resource <span style="color: #66cc66;">=</span> hc_token.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span><span style="color: black;">&#40;</span>COMMAND % <span style="color: black;">&#40;</span>hc_bits<span style="color: #66cc66;">,</span>hc_resource<span style="color: #66cc66;">,</span>hc_token<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shell<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: #66cc66;">,</span> stderr<span style="color: #66cc66;">=</span><span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: #66cc66;">,</span> stdout<span style="color: #66cc66;">=</span><span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out <span style="color: #66cc66;">=</span> p.<span style="color: black;">stderr</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token_status.<span style="color: black;">append</span><span style="color: black;">&#40;</span>out<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token_status.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;No valid tokens for %s found.&quot;</span> % EMAILADDR<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; token_status.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[-- End Hashcash output --]&quot;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>message.<span style="color: black;">headers</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> status <span style="color: #ff7700;font-weight:bold;">in</span> token_status:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>status<span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> tokens:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">''</span><br />
emailmsg.<span style="color: black;">seek</span><span style="color: black;">&#40;</span>message.<span style="color: black;">startofbody</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>emailmsg.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>One thing I do find odd about the code above, is the hashcash binary, when checking tokens, prints to STDERR rather than STDOUT. I&#8217;m guessing this could change in the future, so that&#8217;s something that will need to be watched out for.</p>
<p>So far, the Python script has been working flawless for me. I haven&#8217;t noticed a single hiccup, and it&#8217;s fast, which it should be. However, standard disclaimers apply, such as not coming with any warranty, blah, blah, blah, and if you find any bugs, or have any enhancements (such as supporting multiple email addresses), I&#8217;m all ears. At any rate, I hope you find it helpful, should you wish to get into Hashcash with Mutt.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/29/verifying-hashcash-tokens-with-mutt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hashcash and Mutt</title>
		<link>http://pthree.org/2011/03/24/hashcash-and-mutt/</link>
		<comments>http://pthree.org/2011/03/24/hashcash-and-mutt/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 00:09:58 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1814</guid>
		<description><![CDATA[Introduction I wanted to used Hashcash with Mutt, for nothing more than a curiosity to see if it generates any discussion, and to see if people notice. Further, I&#8217;m a big crypto advocate, and while Hashcash isn&#8217;t exactly crypto, it&#8217;s highly related to it, and uses it. Regardless, I wanted to see if I could [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>I wanted to used Hashcash with Mutt, for nothing more than a curiosity to see if it generates any discussion, and to see if people notice. Further, I&#8217;m a big crypto advocate, and while Hashcash isn&#8217;t exactly crypto, it&#8217;s highly related to it, and uses it. Regardless, I wanted to see if I could seamlessly tie in Hashcash with Mutt, both for minting and verification.</p>
<p>I make the following assumptions:</p>
<ul>
<li>You have Hashcash installed.</li>
<li>You have Mutt installed.</li>
<li>You have Python 2.5 or later installed.</li>
</ul>
<p>With that, let&#8217;s continue.</p>
<p><strong>What is Hashcash?</strong></p>
<p>Hashcash is a proof-of-work protocol, with the motivation of eliminating SPAM. The idea is simple, although we&#8217;ll cover it in greater detail. The TL;DR version, is using Hashcash is about generating tokens, and attaching them to the header of the message you&#8217;re sending. The recipient checks the token for verification. If it passes, then you must not be SPAM, as you&#8217;ve put your computer through enough strenuous work to prove it. If the token fails, you could be SPAM, or you just did it wrong. Either way, it&#8217;s no guarantee that you&#8217;re not a spammer.</p>
<p>Now, the detailed version.</p>
<p>The premise behind Hashcash is that some certain mathematical results are difficult to discover but easy to verify. Factoring large numbers is one such example. So Hashcash is some sort of challenge for your CPU. For example, I say that you cannot comment on my blog, unless you can find the two prime factors of some large number. Once you&#8217;ve paid the work through CPU cycles, and provide the numbers, I multiply them together to see if it gives the result. The work was difficult for you to find, but simple for me to verify. Hashcash is based on this principle.</p>
<p>Using a lot of CPU cycles to answer a question non-interactively is one way to beat spammers at their own game, which Hashcash hopes to address. Rather than looking for large prime factors though, Hashcash is looking for a SHA1 sum of a unique string where the first set of characters in the sum are zero. Because SHA1 can provide 2^160 possible hashes before a collision is found, it shouldn&#8217;t take too much work to find such a string. In other words, the search space is large enough for the work to be reasonable. However, the search space is also large enough, that given a certain criteria, it can be difficult to find the requested string.</p>
<p>Let&#8217;s look at an example. Consider the SHA1 string:</p>
<pre>00000528ba02c4da777839db269fde97de56ddf7</pre>
<p>The first 20 bits of the string are zero. So, this is one such SHA1 hash that would work. The questions are, how did we find it, and what string did we use to generate it? Well, because the first 20 bits of the string are zero, this means that I should only have to search up to 2^20 possible hashes to find the string I&#8217;m looking for. On a moderate system within the last 10 years or so, this should take under a second. Indeed, the SHA1 hash string above was done on an AMD Athlon(tm) XP 1800+ with only 384 MB of PC133 RAM, and it was calculated in 940 milliseconds. The string, or in this case, our &#8220;Hashcash token&#8221; that generated that SHA1 hash is:</p>
<pre>1:20:110321:&#97;&#97;&#114;&#111;&#110;&#46;<u></u>&#116;<i></i>&#111;&#112;&#111;&#110;&#99;&#101;<b></b>&#64;<u></u>&#103;<u></u>&#109;&#97;&#105;<i></i>&#108;&#46;&#99;<i></i>&#111;&#109;<i></i>::Ci2v7/gsBbYY/dhk:0BTS</pre>
<p>You can verify this easily enough:</p>
<pre>echo -n 1:20:110321:&#97;&#97;&#114;&#111;&#110;&#46;<u></u>&#116;<i></i>&#111;&#112;&#111;&#110;&#99;&#101;<b></b>&#64;<u></u>&#103;<u></u>&#109;&#97;&#105;<i></i>&#108;&#46;&#99;<i></i>&#111;&#109;<i></i>::Ci2v7/gsBbYY/dhk:0BTS | sha1sum
00000528ba02c4da777839db269fde97de56ddf7  -</pre>
<p>So, if that is indeed a Hashcash token, then what are all the fields, and how are they used when searching for a SHA1 hash that starts with zeros? Well, the breakdown is thus:</p>
<ol>
<li>The version number.</li>
<li>The claimed bit value.</li>
<li>The date (and time) a stamp was minted.</li>
<li>The resource for which a stamp is minted.</li>
<li>Extensions that a specialized application may want.</li>
<li>A random salt.</li>
<li>The suffix.</li>
</ol>
<p>Hashcash has undergone two revisions thus far. The version number shows the claimed version of the protocol being used. With the latest release of Hashcash, this is &#8220;1&#8243;. &#8220;0&#8243; has shown to have some limitations.</p>
<p>The claimed bit value it telling the verifier of the token how many zeros the resulting SHA1 hash should have. The default is 20-bits, but this can be changed. If the bit value is too low, then it becomes trivial for spammers to reproduce with minimal effort. If the bit value is too high, it may take some considerable time for your CPU to mint the token.</p>
<p>The timestamp is the date when the token was minted. We can take advantage of this for expiry. When the verifier downloads the token, he can keep it in a database. This is useful to hopefully prevent someone else from claiming the same token. However, holding on to tokens indefinitely could be cumbersome, so we can set expiration dates on when the tokens expire, to help manage the database. The default expiration is 28 days.</p>
<p>The resource for which the token is minted is generally the email address of the recipients. However, it&#8217;s flexible enough to be anything. It could be a URL to a webpage, some string of text, or anything that uniquely identifies a certain resource. We&#8217;ll be using email addresses as our resource.</p>
<p>The fifth field is generally left blank, but the protocol specifies that this is used for extensions that any specialized application may want.</p>
<p>The salt is used just like it is used anywhere else. Here, we wish to make our token unique for our resource. The email address and timestamp might not be unique enough to prevent two minted tokens from being the same. So, we add a random, hopefully unique salt here to the token. Once the salt is chosen, just like the timestamp and the resource, it won&#8217;t change for that token. The real grunt work is done with the next field. But, the goal with the salt is to just eliminate the possibility that two people send me an email on the same day, and the minted token is the same. If each salt is randomly chosen, then the tokens will differ.</p>
<p>As stated, this last field is where the real grunt work of your CPU lies. Every previous field is statically set upon instantiation. It is only this field that changes until we find the SHA1 sum that produces the correct number of zeros that we&#8217;ve asked for. Fortunately, the suffix is sequential, starting at zero, and working it&#8217;s way up, base 64, until the appropriate suffix attached to this string gives us the SHA1 we want. As mentioned, if our bit size is 20 bits, by default, then we will only have to work our way through 2^20 possible suffixes, on average, to find the right string that gives us the SHA1 with 20 bits of leading zeros.</p>
<p>The security of the token comes from the fact that there should only be one collision for every 2^160 possible strings in SHA1. Let&#8217;s not get tied up in the cryptanalysis. Suffice it to say, that SHA1 is still holding well in cryptographic circles, and for all practical purposes, we are interested in the amount of work it takes for the CPU to find the right token. When SHA1 becomes broken, and cryptanalysis shows it&#8217;s no longer secure enough for today&#8217;s applications, Hashcash is flexible enough to move to a different cryptographic hashing algorithm by just changing the protocol version. In the meantime, SHA1 works.</p>
<p>Also, given today&#8217;s multicore CPUs, and Moore&#8217;s Law, 20 bits might not be enough work for the CPU to crunch through. Remember, the idea is to beat spammers at their own game. If they can produce mass valid tokens for each spam mail they send, then we should make sure that our bit strength is stronger. Right now, 20 bits seems to be strong enough, but maybe moving it to 24 or 28 bits in the future might be necessary. Just remember the amount of time it takes for your CPU to calculate the work needed for the token.</p>
<p><strong>How Hashcash works with email</strong></p>
<p>When the token is minted, we wish to add the token to our mail header. We can add a token for each recipient in the &#8220;To:&#8221; and &#8220;Cc:&#8221; lines (with special care on how the headers are modified with Bcc: recipients (generally solved by sending separate emails with individual tokens)). What is added to the mail header is the following:</p>
<pre>X-Hashcash: 1:20:110321:&#97;&#97;&#114;&#111;&#110;&#46;<u></u>&#116;<i></i>&#111;&#112;&#111;&#110;&#99;&#101;<b></b>&#64;<u></u>&#103;<u></u>&#109;&#97;&#105;<i></i>&#108;&#46;&#99;<i></i>&#111;&#109;<i></i>::Ci2v7/gsBbYY/dhk:0BTS</pre>
<p>For those using Hashcash, including antispam utilities such as SpamAssassin, looking for the X-Hashcash header in the mail, then verifying that the minted token is valid takes a fraction of a second. But, as we discussed earlier, minting the token takes some time. 20 bits for me takes just under a second. So, now imagine a SPAM ring with control of thousands of zombie computers infected with trojans. There are only 86400 seconds in a day, so if it takes one second to mint a valid token, then a single computer could only send out at most 86400 mails in a day, a far cry from the millions it wishes to send out. So, while it doesn&#8217;t completely eliminate the zombie nets from sending mass emails, it does slow them down considerably.</p>
<p>Yet, for those of us who only send a couple dozen mails per day, it&#8217;s trivial for our CPU to do the work, and doesn&#8217;t slow us down any. Further, those receiving our messages can verify the token is valid in a fraction of the time it took to mint it. As the receiver, you set the price of the token you wish to validate as antispam. Again, 20 bits seems sufficient enough for today, but 24 or 28 bits might need to be your standard in the future.</p>
<p>For those of you who are not using Hashcash, you can simply ignore the header, and move on with your life. It won&#8217;t slow your mail experience down any, and shouldn&#8217;t get in the way of reading or replying to it.</p>
<p><strong>Mutt Configuration</strong></p>
<p>Now that we have a decent understanding of how the Hashcash protocol works, let&#8217;s see how we set this up with Mutt. Thankfully, this is rather straight forward. All you need to add to your ~/.muttrc is:</p>
<pre>set edit_headers="yes"                 # required
set editor="/path/to/mint_hashcash.py" # required
set askcc="yes"                        # recommended, but not required</pre>
<p>This will allow you to edit the mail headers when composing your message with the editor of your choice. The editor is chosen for you in the Python script. I use Vim, so it&#8217;s hardcoded to that. Feel free to change it to your preferred editor of choice. I should also mention at this point that I have only found a way to automate minting tokens with Mutt. I haven&#8217;t found a way yet, although I&#8217;m working on it, to automate the process of verifying tokens, and storing tokens in a database, with Mutt. Hopefully, a followup post can come to fruition when I figure it out (after all, what&#8217;s the point of minting tokens if you can&#8217;t verify others&#8217; tokens yourself?).</p>
<p>The script is here:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span><br />
<span style="color: #808080; font-style: italic;"># Licensed under the public domain</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">fileinput</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">rfc822</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<br />
<span style="color: #dc143c;">subprocess</span>.<span style="color: black;">call</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;vim %s&quot;</span> % <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> shell<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #008000;">file</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span><br />
headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">rfc822</span>.<span style="color: black;">Message</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span><br />
<br />
to_emails <span style="color: #66cc66;">=</span> headers.<span style="color: black;">getaddrlist</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;To&quot;</span><span style="color: black;">&#41;</span><br />
cc_emails <span style="color: #66cc66;">=</span> headers.<span style="color: black;">getaddrlist</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Cc&quot;</span><span style="color: black;">&#41;</span><br />
<br />
email_addrs <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
tokens <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Harvest all email addresses from the header</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #dc143c;">email</span> <span style="color: #ff7700;font-weight:bold;">in</span> to_emails:<br />
&nbsp; &nbsp; email_addrs.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">email</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #dc143c;">email</span> <span style="color: #ff7700;font-weight:bold;">in</span> cc_emails:<br />
&nbsp; &nbsp; email_addrs.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">email</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Remove duplicate emails from the list, requires Python 2.5 and later</span><br />
email_addrs <span style="color: #66cc66;">=</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">set</span><span style="color: black;">&#40;</span>email_addrs<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Check if an appropriate token is already generated for the mail</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> headers.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;X-Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #008000;">list</span> <span style="color: #ff7700;font-weight:bold;">in</span> headers.<span style="color: black;">getheaders</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;X-Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; email_addrs.<span style="color: black;">remove</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> headers.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #008000;">list</span> <span style="color: #ff7700;font-weight:bold;">in</span> headers.<span style="color: black;">getheaders</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Hashcash&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; email_addrs.<span style="color: black;">remove</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Call the hashcash function from the operating system to mint tokens</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #dc143c;">email</span> <span style="color: #ff7700;font-weight:bold;">in</span> email_addrs:<br />
&nbsp; &nbsp; t <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;hashcash -m %s -X -Z 2&quot;</span> % <span style="color: #dc143c;">email</span><span style="color: #66cc66;">,</span> shell<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: #66cc66;">,</span> stdout<span style="color: #66cc66;">=</span><span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; tokens.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t.<span style="color: black;">stdout</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Write the newly minted tokens to the header</span><br />
f <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">fileinput</span>.<span style="color: black;">FileInput</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> inplace<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> f:<br />
&nbsp; &nbsp; line <span style="color: #66cc66;">=</span> line.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> f.<span style="color: black;">lineno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #dc143c;">token</span> <span style="color: #ff7700;font-weight:bold;">in</span> tokens:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">token</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> line<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">continue</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> line<br />
<br />
<span style="color: #008000;">file</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>The code is fairly straight forward. Parse the email headers using RFC 822, grab the necessary email addresses, and mint the tokens as necessary. You&#8217;ll quickly note that &#8220;Bcc:&#8221; addresses aren&#8217;t supported, as minting tokens for those addresses would give them away in the header. I could send separate emails for each Bcc recipient, putting their own token in the header, but I&#8217;m not motivated enough to write that code, and I rarely, if ever, use blind carbon copy.</p>
<p>I&#8217;ve been running the above code now for 2-3 days, trying to break it as best I can, and I haven&#8217;t come across anything. If you do notice a bug, or something sloppy in the code, let me know, and I&#8217;ll make a best attempt at addressing it. However, it seems to be working quite well. The only thing I would mention, is if you have a lot of emails in the &#8220;To:&#8221; or &#8220;Cc:&#8221; fields, it may take some time to mint all those tokens. Just let it do its thing. It will get you back to Mutt. I promise.</p>
<p> <img src='http://pthree.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/24/hashcash-and-mutt/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Various Ways To Shred A Drive</title>
		<link>http://pthree.org/2011/03/09/various-ways-to-shred-a-drive/</link>
		<comments>http://pthree.org/2011/03/09/various-ways-to-shred-a-drive/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 05:00:21 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1793</guid>
		<description><![CDATA[I&#8217;ve been tasked at work with shredding drives. Not physically, mind you, but digitally. Usually, I grab a copy of the latest version of Knoppix, boot up, pull up a terminal, and grab GNU Shred. Something like: shred -n 3 -v /dev/sda It works well enough. However, it doesn&#8217;t display a real useful progress meter, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been tasked at work with shredding drives. Not physically, mind you, but digitally. Usually, I grab a copy of the latest version of Knoppix, boot up, pull up a terminal, and grab GNU Shred. Something like:</p>
<pre>shred -n 3 -v /dev/sda</pre>
<p>It works well enough. However, it doesn&#8217;t display a real useful progress meter, other than how far it&#8217;s done in the wipe, thus leaving it up to you to figure out the speed, while filling up your back scroll in the process. There must be a better way.</p>
<p>I used to &#8220;<a href="http://pthree.org/2008/08/17/digital-graffiti/">leave my mark</a>&#8221; (much like a dog marks a fire hydrant), however, this is quite slow. There are other methods, such as using /dev/urandom, but the entropy from urandom relies on SHA1. While fast, it&#8217;s not the speed demon that is AES or other algorithms. There&#8217;s /dev/zero, but how do I get random bits from zeros? And more importantly, does it push the drive to it&#8217;s bandwidth threshold? Of course, I&#8217;ve heard about DBAN, but I&#8217;ve had issues with it booting on certain hardware. Lastly, I would like to have a good progress meter as the data goes down on the drive.</p>
<p>Here&#8217;s a solution that a friend of mine in an IRC channel suggested:</p>
<pre>openssl enc -aes128 -k "foo" &lt; /dev/zero | pv -trb &gt; /dev/sda</pre>
<p>The great thing with this command is two fold:</p>
<ol>
<li>It&#8217;s fast. It pushes the drive to as fast as it can write data.</li>
<li>It provides a convenient progress meter with &#8220;pv&#8221;</li>
</ol>
<p>Again, I&#8217;m shredding drives with pseudorandom data. I&#8217;m not too concerned about the security of the bits going down on the platter. Per corporate regulation, I need to do 3 passes, and I&#8217;m confident that the bits coming out of the pipe from OpenSSL using AES-128 will be sufficient. So, for doing 3 passes, I can script it easily enough:</p>
<pre>for I in 1 2 3; do
    openssl enc -aes128 -k "$I" &lt; /dev/zero | pv -trb &gt; /dev/sda
done</pre>
<p>That works. 1 drive down, 24 to go&#8230;</p>
<p>If you have various ways you shred your drive, let me know, and I&#8217;ll post it below.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/09/various-ways-to-shred-a-drive/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Bitlbee and OTR</title>
		<link>http://pthree.org/2011/03/08/bitlbee-and-otr/</link>
		<comments>http://pthree.org/2011/03/08/bitlbee-and-otr/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 23:27:18 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Cryptology]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1778</guid>
		<description><![CDATA[I&#8217;m actually surprised that I haven&#8217;t blogged about this before, seeing as though I use it daily. Further, seeing as though I seem to be on a security blogging trip, it only seems fitting to discuss OTR support in Bitlbee now. OTR, or Off-The-Record messaging is the ability to have encrypted and authenticated communication with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m actually surprised that I haven&#8217;t blogged about this before, seeing as though I use it daily. Further, seeing as though I seem to be on a security blogging trip, it only seems fitting to discuss OTR support in Bitlbee now.</p>
<p>OTR, or <a href="http://en.wikipedia.org/wiki/Off-the-Record_Messaging">Off-The-Record messaging</a> is the ability to have encrypted and authenticated communication with full deniability and perfect forward secrecy. The idea is simple. Just as you want to be able to deny anything you say to a journalist when &#8220;off-the-record&#8221;, you should be able to have that ability with instant messaging. It works by not cryptographically signing the message. It&#8217;s just encrypted, and your buddy decrypts it on the other end. Further, each message is encrypted with a one-time AES session key. This means that even if you successfully snatch the AES key for encrypting and decrypting the message, it only applies to the current message, and does nothing for the previous messages, nor does it do anything for you on future messages. Thus, you have perfect forward secrecy with your chat. However, I want to spend some time on the inner workings of how authentication and trust are established, if the messages aren&#8217;t signed for validation.</p>
<p>First, OTR is fully supported in <a href="http://bitlbee.org">Bitlbee</a> version 3.0 and later. For Debian and Ubuntu packages, you will need to install both the &#8220;bitlbee&#8221; and &#8220;bitlbee-plugin-otr&#8221; packages if you want to take advantage of it. Of course, you could grab the source, and compile it in yourself as well. Once installed, you will want to generate master keys for each account you wish to use OTR with. You can get a list of your accounts with &#8220;account list&#8221; in the &#038;bitlbee window of your IRC client:</p>
<pre>15:20 &lt;@aaron&gt; account list
15:20 &lt;@root&gt;  0 (gmail): jabber, &#97;&#97;<u></u>&#114;<u></u>&#111;&#110;&#46;&#116;&#111;&#112;&#111;&#110;&#99;&#101;<b></b><i></i>&#64;<i></i>&#103;<b></b>&#109;&#97;&#105;<u></u>&#108;&#46;&#99;<i></i>&#111;<i></i>&#109; (connected)
15:20 &lt;@root&gt;  1 (twitter): twitter, aarontoponce (connected)
15:20 &lt;@root&gt;  2 (identica): twitter, eightyeight
15:20 &lt;@root&gt; End of account list</pre>
<p>I wish to use OTR with my Gmail account. Thus, I need a key for the account. You can run &#8220;otr keygen &lt;account-no&gt;&#8221; for this:</p>
<pre>otr keygen 0</pre>
<p>It will take some time to generate the key, as it grabs entropy from /dev/random. You may want to add more entropy to the pool by running &#8220;du -sh /&#8221; from a different terminal to help speed things up. Wiggle the mouse, type in text editors, do other things to generate environmental noise. After it&#8217;s finished, you can see the key fingerprint by running &#8220;otr info&#8221;:</p>
<pre>15:28 &lt;@aaron&gt; otr info
15:28 &lt;@root&gt; private keys:
15:28 &lt;@root&gt;   &#97;&#97;<u></u>&#114;<u></u>&#111;&#110;&#46;&#116;&#111;&#112;&#111;&#110;&#99;&#101;<b></b><i></i>&#64;<i></i>&#103;<b></b>&#109;&#97;&#105;<u></u>&#108;&#46;&#99;<i></i>&#111;<i></i>&#109;/jabber - DSA
15:28 &lt;@root&gt;     8D57F662 D991493F 1084427E 31C7E1B9 2074B713
15:28 &lt;@root&gt;
15:28 &lt;@root&gt; connection contexts: (bold=currently encrypted)
15:28 &lt;@root&gt;   (none)</pre>
<p>Now, you&#8217;re ready to communicate with your buddies via OTR. The question that will likely come up now is how do you know if the person you wish to communicate with secretly is really the person you expect? Well, for the years that I&#8217;ve used OTR, I&#8217;ve trusted the individual implicitly. I&#8217;ve communicated with their account enough that when we both decide to &#8220;go secure&#8221; with our chats, that it&#8217;s no big deal. I just trust their keys, they trust mine, and we go about our day. However, you may not want to do that, but want to explicitly acknowledge that you are communicating with who you think.</p>
<p>This can be solved a number of ways:</p>
<ol>
<li>You could call them on the phone, and verify fingerprints verbally.</li>
<li>You could agree on a shared secret before initiating the communication electronically, and use that shared secret to trust the keys.</li>
<li>You could issue a challenge/response question to the opposite party. If they answer correctly, trust the key.</li>
</ol>
<p>Personally, I like the challenge and response system. It&#8217;s not too terrible difficult to think of a question that only your buddy would know, and issue the challenge for them to respond. Of course, they need to do the same with you. This is known as the <a href="http://en.wikipedia.org/wiki/Socialist_millionaire">Socialist Millionaire Protocol</a>. Use &#8220;otr smpq &lt;nick&gt; &lt;question&gt; &lt;answer&gt;&#8221;. It could go something like this:</p>
<pre>otr smpq foobar "What color pen did I use on your whiteboard yesterday? one word, lowercase" red
15:35 &lt;@root&gt; smp: initiating with foobar...</pre>
<p>On the other end, the nick &#8220;foobar&#8221; would have seen this:</p>
<pre>06:42 &lt;@root&gt; smp: initiated by aaron with question: "What color ped did I use on your whiteboard yesterday? one word, lowercase"
06:42 &lt;@root&gt; smp: respond with otr smp aaron &lt;answer&gt;</pre>
<p>At this point, &#8220;foobar&#8221; wishes to respond, as he thinks he knows the question. He would use &#8220;otr smp &lt;nick&gt; &lt;answer&gt;&#8221;:</p>
<pre>otr smp aaron red
06:43 &lt;@root&gt; smp: responding to aaron...
06:43 &lt;@root&gt; smp aaron: correct answer, you are trusted</pre>
<p>At this point, I now trust that foobar is who he says he is, so I can trust any OTR communication from him. However, he hasn&#8217;t verified that I am who he thinks I is. After all, I could be someone pretending to be Aaron, and get sensitive information from him. So, he should issue the same challenge and response to me. Something that only Aaron would know, to thwart any potential baddies. Should I answer correctly, he can then trust my fingerprint, and we will have 2-way OTR communication.</p>
<p>When everything is said and done, Bitlbee will print out the following:</p>
<pre>15:36 &lt;@root&gt; smp foobar: secrets proved equal, fingerprint trusted</pre>
<p>You can also verify it with &#8220;otr info &lt;nick&gt;&#8221;:</p>
<pre>15:37 &lt;@aaron&gt; otr info copecd
15:37 &lt;@root&gt; foobar is foobar@gmail.com/jabber; we are &#97;&#97;<u></u>&#114;<u></u>&#111;&#110;&#46;&#116;&#111;&#112;&#111;&#110;&#99;&#101;<b></b><i></i>&#64;<i></i>&#103;<b></b>&#109;&#97;&#105;<u></u>&#108;&#46;&#99;<i></i>&#111;<i></i>&#109;/jabber to them
15:37 &lt;@root&gt;   otr offer status: none sent
15:37 &lt;@root&gt;   connection state: cleartext
15:37 &lt;@root&gt;   fingerprints: (bold=active)
15:37 &lt;@root&gt;     13C45179 F2A8645B 466463E8 228DBE16 787D1A82 (affirmed)</pre>
<p>As already mentioned, there are other ways for verifying that the person on the other end is who they say they are, and OTR in Bitlbee supports it. You will notice too, that once the fingerprints have been trusted on both sides, the text is green in the chat window. If not trusted, the text is red. As far as I know, there is no way to change the color, or have any other sort of visual clue on whether or not trusted encryption is taking place in the communication.</p>
<p>Also, is should be worthy to note that Bitlbee OTR only supports conversations through Bitlbee, not your IRC client. This means that if you are using Irssi, Weechat, or some other IRC client, Bitlbee OTR won&#8217;t help you for IRC messages. You&#8217;ll need an OTR plugin for that as well. This is definitely a drawback. For example, if you use Irssi like I do, there is an <a href="http://irssi-otr.tuxfamily.org/">OTR plugin for Irssi</a>. Not only will it handle IRC, but any message through IRC, including those of Bitlbee. However, the Irssi OTR plugin hasn&#8217;t been updated in two years, and it has security holes that haven&#8217;t been addressed. The Bitlbee OTR plugin is up-to-date and in my opinion, much more streamlined. I don&#8217;t use private IRC messages much, so the Bitlbee OTR plugin works just fine for me.</p>
<p>Now, start using OTR with Bitlbee. If you love your Bitlbee as much as I do, you will. <img src='http://pthree.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/08/bitlbee-and-otr/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Strong Passwords NEED Entropy</title>
		<link>http://pthree.org/2011/03/07/strong-passwords-need-entropy/</link>
		<comments>http://pthree.org/2011/03/07/strong-passwords-need-entropy/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 03:00:22 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1761</guid>
		<description><![CDATA[I just finished reading an article on Ars Technica titled &#8220;Ask Ars: Where should I store my passwords?&#8220;. There was a specific paragraph that I took issue with, which in turn prompted me to write this post. It is: &#8220;Still, it would take thousands of years to crack an 8-character password when checking both small [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished reading an article on Ars Technica titled &#8220;<a href="http://arstechnica.com/security/guides/2011/03/ask-ars-where-should-i-store-my-passwords.ars">Ask Ars: Where should I store my passwords?</a>&#8220;. There was a specific paragraph that I took issue with, which in turn prompted me to write this post. It is:</p>
<blockquote><p>&#8220;Still, it would take thousands of years to crack an 8-character password when checking both small and capital letters, spaces, and numbers. That&#8217;s on a low-power computer, but the time it takes to crack a string of characters goes up exponentially the more characters you use. So again, use a long password and you can foil even the Watsons of today for long enough that you would probably decide on a whim to change your password before the password is solved.&#8221;</p></blockquote>
<p>I guess I should expect more out of them, but I was disappointed, and I want to use this blog post explaining why. If you wish to write an article about password security, regardless of the angle from which you approach it, if you don&#8217;t mention entropy to your readers, you are doing them a GREAT disservice. Let me rephrase:</p>
<p><u>If you don&#8217;t mention entropy in your article about passwords, you did it wrong.</u></p>
<p>If you&#8217;ve taken physics in secondary or undergraduate school, chances are good that you&#8217;ve heard about entropy. If not, you&#8217;ll learn about it now. Entropy in computer science is very similar to entropy in physics. To put it straight, entropy is defined as the total combination of states that a system can be in. For example, if you have 3 cups, and 4 ping pong balls, how many ways can you arrange all 4 ping pong balls in the 3 cups? Assuming that 4 ping pong balls will fit in 1 cup, and order is not important, you can arrange the ping pong balls 12 different ways: {4,0,0},{3,1,0},{3,0,1},{2,2,0},{2,0,2},{2,1,1},{1,1,2},{1,2,1},{1,3,0},{1,0,3},{0,4,0},{0,0,4} So, this system has an entropy of 12. Entropy in physics is useful to show the Ideal Gas Law, among other things, showing the possible number of states various gases can be in, and it&#8217;s useful for explaining why some things systems behave one way, but not in the reverse (such as temperature &#8220;flowing&#8221; from hot to cold, and not the reverse).</p>
<p>It turns out that entropy has a great deal of use in computer science. For example, on most Unix-like operating systems, there is a /dev/random and /dev/urandom device. These devices are useful for extracting random bits to build encryption keys, one-time session keys, seeds for probability outcomes, etc. These devices hold entropy. In /dev/random, for example, environmental &#8220;noise&#8221; is gathered from the user, such as mouse movements, disk usage, etc. and thrown into an entropy pool. This pool is then hashed with the SHA1 hashing algorithm to provide a total of 160-bits of entropy. Thus, when generating a 160-bit key, the data in /dev/random can be used. If more bits are needed, entropy is gathered by hashing the already hashed bits, as well as gathering additional noise from the environment, and appending to outcome until the number of bits is satisfied. The point is, /dev/random and /dev/urandom are sources of entropy.</p>
<p>So, what does this have to do with passwords? Your password has a certain amount of entropy. This means, that it belongs to a pool of passwords that have the same amount of entropy. The question is, though: &#8220;how do you calculate the amount of entropy in a password?&#8221; Thankfully, we don&#8217;t have too think to terribly hard about this one. If you&#8217;ve taken college algebra, the math is pretty straight forward. <a href="http://en.wikipedia.org/wiki/Entropy_(information_theory)">Entropy</a> in information comes from a branch of probability called &#8220;<a href="http://arstechnica.com/security/guides/2011/03/ask-ars-where-should-i-store-my-passwords.ars">information theory</a>&#8220;. Any message contains some amount of entropy, and we can measure that entropy in binary bits. The formula for calculating this entropy is:</p>
<pre>H = L * log_2(N)</pre>
<p>H is the size of the message measured in binary bits. L is the length of the message- in our case, the length of your password. log_2() is the log function, base 2, and N is the number of possible symbols in the password (only lowercase letters provide 26 possible characters, uppercase provide an additional 26 possible characters, the digits provide 10 possible characters and punctuation provides 32 possible characters on an United States English keyboard). I rewrote the equation, so you could find it using your calculator:</p>
<pre>H = L * log(N) / log(2)</pre>
<p>Having this formula makes calculating the entropy of passwords straight forward. Here are some examples:</p>
<ul>
<li><strong>password</strong>: 38 bits (8 * log_2(26)</li>
<li><strong>RedSox</strong>: 34 bits (6 * log_2(52))</li>
<li><strong>B1gbRother|$alw4ysriGHt!?</strong>: 164 bits (26 * log_2(94))</li>
<li><strong>deer2010</strong>: 41 bits (8 * log_2(36))</li>
<li><strong>l33th4x0r</strong>: 46 bits (9 * log_2(36))</li>
<li><strong>!Aaron08071999Keri|</strong>: 131 bits (28 * log_2(94))</li>
<li><strong>PassWord</strong>: 46 bits (8 * log_2(52))</li>
<li><strong>4pRte!aii@3</strong>: 78 bits (12 * log_2(94))</li>
</ul>
<p><u>Question</u>: what gives you more entropy per bit- length or possible characters? If you passed college algebra, you would know that the answer is length, not total possible characters (if you need to think about this, graph the log function on your calculator, then graph a multiple of it). Of course, you shouldn&#8217;t ignore using lowercase, uppercase, numbers and punctuation in your password, but they won&#8217;t buy you as much entropy as length will. Thus, I prefer the term &#8220;passphrase&#8221; over &#8220;password&#8221;, as it implies this concept to the user.</p>
<p>Here&#8217;s a table showing the length your password must be given the possible character combinations in your password, if you want a certain entropy. Say you want an entropy of 64-bits using only numbers, it would need to be 20 characters long. If you wanted an entropy of 80 bits using characters from the entire ASCII set, it would only need to be 13 characters long.</p>
<table border="1" class="table class handout docutils">
<colgroup>
<col width="19%" />
<col width="13%" />
<col width="15%" />
<col width="21%" />
<col width="32%" />
</colgroup>
<thead valign="bottom">
<tr>
<th class="head">Entropy (H)</th>
<th class="head">Numbers</th>
<th class="head">Alphabet</th>
<th class="head">Alphanumeric</th>
<th class="head">All ASCII characters</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>32</td>
<td>10</td>
<td>6</td>
<td>6</td>
<td>5</td>
</tr>
<tr>
<td>40</td>
<td>13</td>
<td>8</td>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>64</td>
<td>20</td>
<td>12</td>
<td>11</td>
<td>10</td>
</tr>
<tr>
<td>80</td>
<td>25</td>
<td>15</td>
<td>14</td>
<td>13</td>
</tr>
<tr>
<td>96</td>
<td>29</td>
<td>17</td>
<td>17</td>
<td>15</td>
</tr>
<tr>
<td>128</td>
<td>39</td>
<td>23</td>
<td>22</td>
<td>20</td>
</tr>
<tr>
<td>160</td>
<td>49</td>
<td>29</td>
<td>27</td>
<td>25</td>
</tr>
<tr>
<td>192</td>
<td>58</td>
<td>34</td>
<td>33</td>
<td>30</td>
</tr>
<tr>
<td>224</td>
<td>68</td>
<td>40</td>
<td>38</td>
<td>35</td>
</tr>
<tr>
<td>256</td>
<td>78</td>
<td>45</td>
<td>43</td>
<td>40</td>
</tr>
<tr>
<td>384</td>
<td>116</td>
<td>68</td>
<td>65</td>
<td>59</td>
</tr>
<tr>
<td>512</td>
<td>155</td>
<td>90</td>
<td>86</td>
<td>79</td>
</tr>
<tr>
<td>1024</td>
<td>309</td>
<td>180</td>
<td>172</td>
<td>157</td>
</tr>
</tbody>
</table>
<p>So, how much entropy should you have in your password? What is considered &#8220;strong&#8221;? Well, let us look at <a href="http://distributed.net">Distributed.net</a>. They are working on two projects: Optimal Golomb Rulers and cracking an RSA 72-bit message. Let&#8217;s look at the RSA project. In January 1997, <a href="http://www.rsa.com/rsalabs/node.asp?id=2100">RSA Laboratories issued a secret key challenge</a>. They generated random keys ranging from 40-bits to 128-bits. They provided the ciphertext, and a $1,000 prize to the person who find the private key that generated the message, for every message. In order to know whether or not you found the key, they gave you the first two words of the message.</p>
<p>Currently, as already mentioned, Distributed.net is working on the 72-bit key from that challenge. If you check the <a href="http://stats.distributed.net/projects.php?project_id=5">stats page</a>, you can see that it has been running for 3,017 days as of the writing of this post, and at the current pace, it would take roughly 200,000 days to search the entire key space. Now, of course it is probable that they will find the key before exhausting the entire space, but knowing when that will be is anyone&#8217;s guess. Needless to say, 200,000 days or about 540 years at the current pace is substantially large. If they kept that pace up for the 80-bit key, it would take them roughly 140,000 years to search the entire space. However, it only took them 1,726 days, or 4-and-a-half years, to find the 64-bit key, and only 193 days, or 6 months to find the 56-bit key.</p>
<p>So, I think that should give you a good rule of thumb to go by. 72-bits of entropy for your password seems strong enough for the short term, but it wouldn&#8217;t hurt to probably increase your passwords to contain 80-bits of entropy for the long term. Of course, I don&#8217;t think I need to mention not using your names, birthdates, or other silliness in your password. That&#8217;s been beaten to death plenty online. Search Google for generating strong passwords, and you&#8217;ll find plenty of them (all of which don&#8217;t mention entropy either, I would be willing to bet).</p>
<p>Now, to be fair, the Ars Technica article mostly mentioned STORING your passwords, not how to create strong ones. <a href="http://pthree.org/2010/09/21/password-cards/">I&#8217;ve already written about this before</a>, and I think it&#8217;s the perfect solution. <a href="http://passwordcard.org">http://passwordcard.org</a> is the exact solution for storing strong passwords that have a good amount of entropy in them. The great thing about it too, is it does not require any software once generated. It stays with you in your wallet, so if you visit a computer that doesn&#8217;t have your encrypted database, or you are not allowed to install software on the machine so you can restore your password database, the password card is the perfect fit. It&#8217;s entirely platform-independent. Just pull it out of your wallet or purse, type in your password, and move on with your life. All you need to remember on the card is three things:</p>
<ol>
<li>The starting column and row of your password.</li>
<li>The length of the password.</li>
<li>The path your password takes on the card.</li>
</ol>
<p><img src="http://lh4.ggpht.com/_UjZEx7iINYc/TJjZODXztII/AAAAAAAAA3M/H50NKHna3vQ/s800/password-card-example.png" /></p>
<p>I&#8217;ve been using it since it first &#8220;released&#8221;, and I use it for all my passwords on all my accounts, web-based, key-based or account-based. Every password is unique, they all contain more than 100-bits of entropy, and every password follows the &#8220;best rules&#8221; for creating strong passwords. I&#8217;ve typed many of them enough to have them memorized; I rarely pull out my card (there is also an Android and Apple application if you want).</p>
<p>So, next time you read an article about password strength, do a quick search for the word &#8220;entropy&#8221;. If it&#8217;s not mentioned, take the article in stride, or at least notify the author of this post, and that they should discuss entropy to their readers. Entropy is your friend.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/07/strong-passwords-need-entropy/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>The Sad State of Hashcash</title>
		<link>http://pthree.org/2011/03/03/the-sad-state-of-hashcash/</link>
		<comments>http://pthree.org/2011/03/03/the-sad-state-of-hashcash/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 03:42:06 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1755</guid>
		<description><![CDATA[So today, I received an email from one of the readers of this blog. He wanted to get into OpenPGP with his email, and asked if I could help him get started with some tutorials, how-tos, etc. I was flattered that he valued my opinion. So, I responded to each of his questions and discussion [...]]]></description>
			<content:encoded><![CDATA[<p>So today, I received an email from one of the readers of this blog. He wanted to get into OpenPGP with his email, and asked if I could help him get started with some tutorials, how-tos, etc. I was flattered that he valued my opinion. So, I responded to each of his questions and discussion points the best I could. However, during the reply, I reminded myself of <a href="http://hashcash.org">Hashcash</a>.</p>
<p>Hashcash is a really slick concept. The motivation is to combat spammers by using your CPU to calculate a SHA1 string starting with the first 20-bits as zeros based on a random number. Basically, a &#8220;<a href="http://en.wikipedia.org/wiki/Proof-of-work_system">proof-of-work</a>&#8221; system. If the random number, combined with the timestamp and the recipient&#8217;s email address, doesn&#8217;t provide those first 20-bits of zeros, a new random number is chosen and hashed. Once the random number is found, it&#8217;s attached to the header of the email, and sent. The recipient of the email can then hash the full string, and see if the first 20-bits of the resulting SHA1 are zeros. If so, along with some other validity checks, then the hash is considered valid, and you can rest assured that the email was not sent by a spammer.</p>
<p>A valid stamp:</p>
<pre>1:20:110303:&#97;&#97;&#114;&#111;&#110;&#46;&#116;&#111;&#112;&#111;&#110;&#99;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;::d2e1fcbcbdb8bf08b804b65c4d61f5be:2b1825ea77c0bb82</pre>
<p>You can verify this with:</p>
<pre>% echo -n '1:20:110303:&#97;&#97;&#114;&#111;&#110;&#46;&#116;&#111;&#112;&#111;&#110;&#99;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;::d2e1fcbcbdb8bf08b804b65c4d61f5be:2b1825ea77c0bb82' | sha1sum
00000d0a92fad840b05009c8692f43593c692589  -</pre>
<p>Notice how the first 20-bits of the SHA1 hash are zeros? This is a valid hash based on the random number, the email address and the timestamp.</p>
<p>How does this defeat the spammers? Well, because finding the right random number that will produce a hash with the first 20-bits of zeros is computationally expensive. There will be one in at least 2^20 hashes, but the search in finding one is expensive. A modern computer can find one in under a second. But, if you wish to send bulk emails all at once, you need to create a hash &#8220;token&#8221; or &#8220;stamp&#8221; for each one. Due to the design of the algorithm to be slow, this will seriously hinder your ability to be efficient at sending bulk mail. Spammers be damned.</p>
<p>The proof-of-idea work is slick. The sender of an email has done the work necessary, and you can easily validate the work is been done much faster than it took to create. However, it appears from the website that all activity on the software has been abandoned since 2006, including updating the web page. Software is hard to find, and for the software that does exist, it&#8217;s only compatible with very specific versions of software, leaving old or new software out of the game.</p>
<p>A couple examples.</p>
<p><a href="http://pennypost.sourceforge.net/PennyPost">Penny Post</a> is an extension for Thunderbird. The SourceForge page houses the extension that is only compatible with Thunderbird versions earlier than 3.0. However, <a href="http://github.com/jonasbits/PennyPostTB">there is a Github project</a> working on a Thunderbird 3.0-compatible extension. However, this extension is not compatible with Thunderbird 3.1. The extension page has also been pulled from <a href="https://addons.mozilla.org/en-US/thunderbird/addon/5553">Mozilla Addons</a>.</p>
<p><a href="http://www.hashcash.org/mail/mua/hc-sendmail/">Hashcash-sendmail</a> is a Perl script for Mutt. It works by coupling the hashcash binary and the sendmail binary together to deliver your stamped mail. However, if you are using Mutt&#8217;s buitin SMTP support, then the Perl script isn&#8217;t usable. Also, it appears that the author of the script has <a href="http://www.toehold.com/~kyle/hashcash/">lost his domain</a>, and there hasn&#8217;t been any updates since 2004, it seems.</p>
<p>Lastly, I have a Windows XP laptop for work with Thunderbird 3.1 installed. Of course, Penny Post isn&#8217;t compatible with 3.1, so I&#8217;m already out of luck. However, even the <a href="http://www.hashcash.org/tool/windows/">Windows Hashcash binaries</a> are out of date by several years.</p>
<p>Nevermind trying to implement it into more popular MUAs, like webmail clients (Gmail, Yahoo!, MSN, AOL, etc.), Outlook, Groupwise, etc. It just doesn&#8217;t exist. Yet, <a href="https://spamassassin.apache.org/full/3.0.x/dist/doc/Mail_SpamAssassin_Plugin_Hashcash.html">SpamAssassin has full support</a> for identifying the &#8220;X-Hashcash&#8221; email header.</p>
<p>No matter where I look, I reach dead ends. This is unfortunate, because I see Hashcash as a slick way of beating spam, yet it appears that the spammers are laughing all the way to the bank. They&#8217;re not worried because no one is using it. And I have a feeling that no one is using it, because no one is developing anything for it. Everything out there is at least 5 years old and aging.</p>
<p>Maybe another slick proof-of-work system will come along. Who knows? I would like to work it into my daily email routine, but it appears that doing so with the current state of affairs is futile. I guess I could work on developing scripts and such that could be easily implemented into various MUAs, but with the amount of stuff I want to do after graduation, I&#8217;m guessing it&#8217;s fairly low on the priority list. </p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/03/the-sad-state-of-hashcash/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Created A PGP Key Signing Policy</title>
		<link>http://pthree.org/2011/03/01/created-a-pgp-key-signing-policy/</link>
		<comments>http://pthree.org/2011/03/01/created-a-pgp-key-signing-policy/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 02:54:56 +0000</pubDate>
		<dc:creator>Aaron Toponce</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://pthree.org/?p=1752</guid>
		<description><![CDATA[I just created a PGP/GPG key signing policy. I&#8217;ve never set one before, so there it is. The motivation is three-fold: I want raise awareness for encrypted email, I want to expand the Web of Trust and I want to sign keys. I believe we&#8217;ve gotten too anal retentive about the rituals of signing each [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pthree.org/my-pgp-key-signing-policy/">I just created a PGP/GPG key signing policy</a>. I&#8217;ve never set one before, so there it is.</p>
<p>The motivation is three-fold: I want raise awareness for encrypted email, I want to expand the Web of Trust and I want to sign keys. I believe we&#8217;ve gotten too anal retentive about the rituals of signing each others keys, and I would like to bring it more to the forefront of the general public. There is no reason why email shouldn&#8217;t be encrypted 100% of the time, and doing the Song and Dance of creating a conga line, reciting fingerprints, and verifying identifications has probably gone a little overboard.</p>
<p>Thus, on my policy page, you&#8217;ll notice that I&#8217;m willing to sign your key if you just send me $1 USD along with your email address and key. I&#8217;ll return the $1 after I&#8217;ve signed it. Or, you can send me a colored scan of your U.S. passport or driver license, and I&#8217;ll sign your key. Crazy? Maybe. I&#8217;m fairly confident, however, that the government, or powerful enemies, isn&#8217;t planning a coordinated attack against my identity.</p>
]]></content:encoded>
			<wfw:commentRss>http://pthree.org/2011/03/01/created-a-pgp-key-signing-policy/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

