<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Alice, Bob, and Mallory: Category Cryptography</title>
    <link>http://www.alicebobandmallory.com/articles/category/cryptography</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>metasyntactics</description>
    <item>
      <title>Encrypt images in JavaScript</title>
      <description>&lt;p&gt;In browsers that supports the HTML5 &lt;a href="http://en.wikipedia.org/wiki/Canvas_element"&gt;canvas &lt;/a&gt; it's possible to read the raw image data. I figured that this makes it possible to encrypt images on the client. Why would one ever want to encrypt images client-side? One use case could be to send images to a server that only those who know the password can decrypt (host-proof hosting).&lt;/p&gt;

&lt;p&gt;I used &lt;a href="http://code.google.com/p/crypto-js/"&gt;Crypto-JS&lt;/a&gt; to encrypt with &lt;a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard"&gt;AES&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Rabbit_%28cipher%29"&gt;Rabbit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First I get the &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspixelarray"&gt;CanvasPixelArray&lt;/a&gt; from the &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata"&gt;ImageData&lt;/a&gt; object.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; ctx = document.getElementById(&lt;span style="color:#04D"&gt;'l&lt;/span&gt;eif&lt;span style="color:#04D"&gt;')&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                  .getContext(&lt;span style="color:#04D"&gt;'2&lt;/span&gt;d&lt;span style="color:#04D"&gt;')&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; imgd = ctx.getImageData(&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;,&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;,width,height);&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; pixelArray = imgd.data;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;
The pixel array has four bytes for each pixel as &lt;a href="http://en.wikipedia.org/wiki/RGBA_color_space"&gt;RGBA&lt;/a&gt; but Crypto-JS encrypts a string, not an array. At first I used &lt;code&gt;.join()&lt;/code&gt; and &lt;code&gt;.split(",")&lt;/code&gt; to get from array to string and back. It was slow and the string got much longer than it had to be. Actually four times longer. To save even more space I decided to discard the alpha channel.  
&lt;br/&gt;
&lt;br/&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#080;font-weight:bold"&gt;function&lt;/span&gt; canvasArrToString(a) {&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; s=&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#666"&gt;// Removes alpha to save space.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;for&lt;/span&gt; (&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; i=&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;; i&amp;lt;pix.length; i+=&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;    s+=(String.fromCharCode(pix[i])&lt;tt&gt;
&lt;/tt&gt;        + String.fromCharCode(pix[i+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;        + String.fromCharCode(pix[i+&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;]));&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; s;&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;
That string is what I then encrypt. I sticked to `+=` after reading &lt;a href="http://www.sitepen.com/blog/2008/05/09/string-performance-an-analysis/"&gt;String Performance an Analysis&lt;/a&gt;.  
&lt;br/&gt;
&lt;br/&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; encrypted = Crypto.Rabbit.encrypt(imageString, password);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;
I used a small 160x120 pixels image. With four bytes for each pixels that gives 76800 bytes. Even though I stripped the alpha channel the encrypted image still takes up 124680 bytes, 1.62 times bigger. Using  `.join()` it was 384736 bytes, 5 times bigger. One cause for it still being larger than the original image is that Crypto-JS returns a &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt; encoded string and that adds something like 37%.  
&lt;br&gt;
&lt;br&gt;
Before I could write it back to the canvas I had to convert it to an array again.  
&lt;br/&gt;
&lt;br/&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#080;font-weight:bold"&gt;function&lt;/span&gt; canvasStringToArr(s) {&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; arr=[];&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;for&lt;/span&gt; (&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; i=&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;; i&amp;lt;s.length; i+=&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;for&lt;/span&gt; (&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; j=&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;; j&amp;lt;&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;; j++) {&lt;tt&gt;
&lt;/tt&gt;      arr.push(s.substring(i+j,i+j+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;).charCodeAt());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;    arr.push(&lt;span style="color:#00D;font-weight:bold"&gt;255&lt;/span&gt;); &lt;span style="color:#666"&gt;// Hardcodes alpha to 255.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; arr;&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;
Decryption is simple.
&lt;br/&gt;
&lt;br/&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; arr=canvasStringToArr(&lt;tt&gt;
&lt;/tt&gt;              Crypto.Rabbit.decrypt(encryptedString, password));&lt;tt&gt;
&lt;/tt&gt;imgd.data=arr;&lt;tt&gt;
&lt;/tt&gt;ctx.putImageData(imgd,&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;,&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;br/&gt;

Tested in Firefox, Google Chrome, WebKit3.1 (Android 2.2), iOS 4.1, and a very recent release of Opera.  
&lt;br/&gt;
&lt;br/&gt;
&lt;table style="width: 366pt; border-collapse: collapse;" width="487" border="0" cellpadding="0" cellspacing="0"&gt;

&lt;colgroup&gt;&lt;col style="width: 160pt;" width="213"&gt;&lt;col style="width: 62pt;" width="82"&gt;&lt;col style="width: 48pt;" width="64" span="3"&gt;&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border: 0.5pt solid windowtext; background-color: transparent; width: 160pt; min-height: 12.75pt;" width="213" height="17"&gt;
&lt;strong&gt;&lt;font face="Arial" size="2"&gt;Browser / Action in milliseconds&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="border-width: 0.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: windowtext; background-color: transparent; width: 62pt;" width="82"&gt;
&lt;strong&gt;&lt;font face="Arial" size="2"&gt;Enc. Rabbit&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="border-width: 0.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: windowtext; background-color: transparent; width: 48pt;" width="64"&gt;
&lt;strong&gt;&lt;font face="Arial" size="2"&gt;Dec. Rabbit&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="border-width: 0.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: windowtext; background-color: transparent; width: 48pt;" width="64"&gt;
&lt;strong&gt;&lt;font face="Arial" size="2"&gt;Enc. AES&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="border-width: 0.5pt 0.5pt 0.5pt medium; border-style: solid solid solid none; border-color: windowtext; background-color: transparent; width: 48pt;" width="64"&gt;
&lt;strong&gt;&lt;font face="Arial" size="2"&gt;Dec. AES&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Google Chrome 6.0.472.62 C2D@1.86GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;136&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;130&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;236&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;222&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Opera 10.63 P4HT@3GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;246&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;252&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;438&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;437&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Google Chrome 6.0.472.63 P4HT@3GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;280&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;648&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;303&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;547&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Firefox 3.6.10 Phenom II X4 945@3GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;494&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;321&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1876&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1745&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Firefox 3.6.10 i5@3,5GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;366&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;193&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1639&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1410&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Firefox 3.6.10 C2D@1.86GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;760&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;367&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2417&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1983&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;

&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Firefox 3.6.10 P4HT@3GHz&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;880&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;440&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;4000&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;3500&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;Nokia N900 Chrome&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1764&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;1975&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2509&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2508&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;WebKit 3.1 (HTC Desire)&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2000&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2200&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;3300&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;3400&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;iPhone 3GS iOS 4.1&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2130&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;2071&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;7198&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;7131&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;N900 Firefox Mobile&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;3411&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;3508&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;19308&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;19466&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;N900 native (MicroB)&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;4681&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;4300&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;24560&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;20973&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;tr style="min-height: 12.75pt;" height="17"&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt; border-style: none solid solid; border-color: windowtext; background-color: transparent; min-height: 12.75pt;" height="17"&gt;
&lt;font face="Arial" size="2"&gt;X10 Mini Pro, Android 1.6&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;7464&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;" align="right"&gt;
&lt;font face="Arial" size="2"&gt;7747&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;"&gt;
&lt;font face="Arial" size="2"&gt;timeout&lt;/font&gt;&lt;/td&gt;
&lt;td style="border-width: medium 0.5pt 0.5pt medium; border-style: none solid solid none; border-color: windowtext; background-color: transparent;"&gt;
&lt;font face="Arial" size="2"&gt;timeout&lt;/font&gt;&lt;/td&gt;

&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;  &lt;/p&gt;

&lt;p&gt;A &lt;a href="http://plea.se/me/cryptimage.html"&gt;demo&lt;/a&gt; can be found &lt;a href="http://plea.se/me/cryptimage.html"&gt;here&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;
&lt;font color="red"&gt;EDIT 2010-10-17&lt;/font&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Warning&lt;/strong&gt; I've noticed that the encrypted strings aren't compatible between browsers. At least not in between Google Chrome and Firefox. I don't know why.&lt;/p&gt;

&lt;p&gt;I also tried to add deflate/inflate and that compresses my test image to a third of the raw size and in Google Chrome it also halved the execution time. In Firefox Rabbit got about 50% slower and AES about 50% faster with deflate/inflate.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://plea.se/me/cryptimage2.html"&gt;Here's a demo of this&lt;/a&gt;. 
&lt;br&gt;&lt;br&gt;
&lt;font color="red"&gt;EDIT 2010-10-21&lt;/font&gt;&lt;br&gt;&lt;br&gt;
Added a preprocessing filter of the raw image data inspired by &lt;a href="http://www.w3.org/TR/PNG-Filters.html"&gt;PNG&lt;/a&gt; type 1 sub filter. Presented my idea to Fredrik and he returned a formula. Thanks!
&lt;br&gt;
The result wasn't what I had hoped for, a measly 6% smaller. I also tried to save the image as real PNG and that one is 20480 bytes.
20480*1.37=28057 bytes (Base64 overhead) and my homemade format is 38336 bytes. Not a fantastic result but not that horrible either.
&lt;br&gt;&lt;br&gt;
&lt;a href="http://plea.se/me/cryptimage3.html"&gt;Here's a demo of this&lt;/a&gt;. &lt;/p&gt;</description>
      <pubDate>Thu, 14 Oct 2010 23:40:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1cb3eec8-d3a1-48f2-bb32-024bbf4cbe96</guid>
      <author>Jonas Elfström</author>
      <link>http://www.alicebobandmallory.com/articles/2010/10/14/encrypt-images-in-javascript</link>
      <category>Cryptography</category>
      <category>JavaScript</category>
    </item>
    <item>
      <title>Breaking simple ciphers</title>
      <description>&lt;p&gt;The last few days I've happened to stumble over a couple of ciphers and I just couldn't help myself from trying to break them.&lt;/p&gt;

&lt;h3&gt;The Lost Symbol&lt;/h3&gt;

&lt;p&gt;Dan Brown has a new book coming out and part of the promotion is this  cipher text "AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW". 
The WQW, QQ and three of the words ending with an A made me believe we could be dealing with a substitution cipher and maybe even a Caesar cipher, the most simple of them all.&lt;/p&gt;

&lt;p&gt;My usual tool of choice is Ruby and in this case the splendid Interactive Ruby Shell.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt; irb&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; s=&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;caesar&lt;/span&gt;(text,n)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   alphas=(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;A&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;..&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;Z&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;).to_a*&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   text.tr(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;A-Z&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, alphas[n..n+&lt;span style="color:#00D;font-weight:bold"&gt;26&lt;/span&gt;].join)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;25&lt;/span&gt;) &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt; |n| puts &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;%2d. %s&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [n, caesar(s,n)] &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;BPGBDGTPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GTAXCFJD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FJPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;APITGXRXPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PRRTEX&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;CQHCEHUQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HUBYDGKE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GKQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BQJUHYSYQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QSSUFY&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;DRIDFIVRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IVCZEHLF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HLRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CRKVIZTZRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RTTVGZ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;ESJEGJWSE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JWDAFIMG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IMSE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DSLWJAUASE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SUUWHA&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;5&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;FTKFHKXTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KXEBGJNH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JNTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ETMXKBVBTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TVVXIB&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;6&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;GULGILYUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LYFCHKOI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KOUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FUNYLCWCUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UWWYJC&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;7&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;HVMHJMZVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MZGDILPJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LPVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GVOZMDXDVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VXXZKD&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;8&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;IWNIKNAWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NAHEJMQK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MQWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HWPANEYEWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WYYALE&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;9&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;JXOJLOBXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;OBIFKNRL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NRXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IXQBOFZFXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XZZBMF&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;10&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;KYPKMPCYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PCJGLOSM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;OSYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JYRCPGAGYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YAACNG&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;11&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;LZQLNQDZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QDKHMPTN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PTZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KZSDQHBHZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZBBDOH&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;12&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;MARMOREAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RELINQUO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QUAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LATERICIAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ACCEPI&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;13&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;NBSNPSFBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SFMJORVP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RVBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MBUFSJDJBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BDDFQJ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;14&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;OCTOQTGCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TGNKPSWQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SWCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NCVGTKEKCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CEEGRK&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;15&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;PDUPRUHDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UHOLQTXR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TXDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ODWHULFLDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DFFHSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;16&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;QEVQSVIEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VIPMRUYS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UYEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PEXIVMGMEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;EGGITM&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;17&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;RFWRTWJFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WJQNSVZT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VZFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QFYJWNHNFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FHHJUN&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;18&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;SGXSUXKGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XKROTWAU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WAGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RGZKXOIOGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GIIKVO&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;19&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;THYTVYLHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YLSPUXBV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XBHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SHALYPJPHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HJJLWP&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;20&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;UIZUWZMIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZMTQVYCW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YCIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TIBMZQKQIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IKKMXQ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;21&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;VJAVXANJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ANURWZDX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZDJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UJCNARLRJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JLLNYR&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;22&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;WKBWYBOKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BOVSXAEY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;AEKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VKDOBSMSKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KMMOZS&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;23&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;XLCXZCPLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CPWTYBFZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BFLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WLEPCTNTLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LNNPAT&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;24&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;YMDYADQMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DQXUZCGA&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CGMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XMFQDUOUMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MOOQBU&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;25&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;ZNEZBERNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ERYVADHB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DHNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YNGREVPVNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NPPRCV&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Take a closer look at row 12.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MARMOREAM RELINQUO QUAM LATERICIAM ACCEPI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I found Rome a city of bricks and left it a city of marble.&lt;/em&gt; - Google tells me it's Augustus.&lt;/p&gt;

&lt;p&gt;The code is not the most clear I've written but if you read Ruby in your sleep you can skip this part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;('A'..'Z')&lt;/strong&gt; is a range in Ruby. Another, maybe more obvious, example of a range is &lt;strong&gt;(0..7)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.to_a&lt;/strong&gt; could be read as to_array and unsurprisingly it converts a range to an array. &lt;strong&gt;(0..7).to_a&lt;/strong&gt; will create  &lt;strong&gt;[0, 1, 2, 3, 4, 5, 6, 7]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The operator * for arrays appends n copies of the array. Thus &lt;strong&gt;[0,1,2]*2&lt;/strong&gt; will create  &lt;strong&gt;[0,1,2,0,1,2]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ruby-doc.org/core/classes/String.html#M000845"&gt;String#tr&lt;/a&gt; works the same way as the Unix command tr, it translates the characters in the string according to the from and to parameters. &lt;/p&gt;

&lt;p&gt;At last &lt;strong&gt;.join&lt;/strong&gt; converts the array to a string.&lt;/p&gt;

&lt;h3&gt;The recruiting agency&lt;/h3&gt;

&lt;p&gt;A government agency responsible for signals intelligence is hiring. Among the qualifications they are looking for is the ability to break a certain cipher. I will not publish their cipher here but instead one of my own, constructed in the same way as theirs.&lt;pre&gt;"VGhpcyBpcyBleGNsdXNpdmUgZm9yIHlvdSwgb3I/IGMNR0d
LCkZPXgpTRV8K\nTENEQ1lCCkhfXgpoT1NFRElPCkNZCksKSE9eXk
9YCklYU1peRU1YS1pCT1gK\nXkJLRAp5SUJET0NPWAQ="&lt;/pre&gt;
At first glance it looked like Base64 and the ending "=" made it even more likely.&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt; irb&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; require &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;base64&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; cipher = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;VGhpcyBpcyBleGNsdXNpdmUgZm9yIHlvdSwgb3I/IGMNR0dLCkZPXgpTRV8K&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;TENEQ1lCCkhfXgpoT1NFRElPCkNZCksKSE9eXk9YCklYU1peRU1YS1pCT1gK&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;XkJLRAp5SUJET0NPWAQ=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; decoded=&lt;span style="color:#036;font-weight:bold"&gt;Base64&lt;/span&gt;.decode64(cipher)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;This is exclusive for you, or? c&lt;/span&gt;&lt;span style="color:#b0b"&gt;\r&lt;/span&gt;&lt;span style=""&gt;GGK&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;FO^&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;SE&lt;em&gt;&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;LCDCYB&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;H&lt;/em&gt;^&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;hOSEDIO&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;CY&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;K&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;HO^^OX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;IXSZ^EMXKZBOX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;^BKD&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;yIBDOCOX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\004&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;

&lt;p&gt;So it's Base64 but to no surprise it didn't end there. The "This is exclusive for you, or?" hinted at XOR so I tried XORing the text with 0-255.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt;&amp;gt; code=decoded[&lt;span style="color:#00D;font-weight:bold"&gt;31&lt;/span&gt;..decoded.length].split(&lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.open(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;xor.txt&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;w&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;) { |file|&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;?&amp;gt;&lt;/span&gt;   &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;255&lt;/span&gt;) {|n|&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;?&amp;gt;&lt;/span&gt;     file.write(n.to_s + &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;     code.each {|c| file.write( (c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]^n).chr ) }&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;     file.write(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   }&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;A quick look in the file told me that XORing with 42 was the solution.&lt;/p&gt;

&lt;p&gt;Now you know how to break two of the most simple cipher methods. Use the knowledge wisely. :)&lt;/p&gt;</description>
      <pubDate>Wed, 16 Sep 2009 20:19:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:bfe9c11f-97c5-458b-a238-2304814e7794</guid>
      <author>Jonas Elfström</author>
      <link>http://www.alicebobandmallory.com/articles/2009/09/16/breaking-simple-ciphers</link>
      <category>Ruby</category>
      <category>Cryptography</category>
    </item>
    <item>
      <title>Blowfish in the URL</title>
      <description>&lt;p&gt;Sometimes you do not want to show the database id for a row in the URL. The reason could be that you do not want someone to be able to scan through all the data.&lt;/p&gt;

&lt;p&gt;One solution is to use &lt;a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier"&gt;GUID's&lt;/a&gt; but they have drawbacks and one of them is that they add a considerable length to the URL. The shortest URL-safe representation of a GUID I've seen is &lt;a href="http://tools.assembla.com/breakout/wiki/FreeSoftware"&gt;22 characters&lt;/a&gt; but usually they are 36 characters.&lt;/p&gt;

&lt;p&gt;Depending on how your id's are implemented a much shorter way could be to simply to encrypt them.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;-example that Blowfish encrypts, Base64 encodes and URL-encodes an integer value. You can get crypt as a gem:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem install crypt&lt;/code&gt;&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;rubygems&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;crypt/blowfish&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;Base64&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;blowfish = &lt;span style="color:#036;font-weight:bold"&gt;Crypt&lt;/span&gt;::&lt;span style="color:#036;font-weight:bold"&gt;Blowfish&lt;/span&gt;.new(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;A key up to 56 bytes long&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;plainId=&lt;span style="color:#00D;font-weight:bold"&gt;123456&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;encrypted = blowfish.encrypt_block(plainId.to_s.ljust(&lt;span style="color:#00D;font-weight:bold"&gt;8&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;idForURL = &lt;span style="color:#036;font-weight:bold"&gt;URI&lt;/span&gt;.escape((&lt;span style="color:#036;font-weight:bold"&gt;Base64&lt;/span&gt;.encode64(encrypted).strip))&lt;tt&gt;
&lt;/tt&gt;decryptedId = blowfish.decrypt_block(  &lt;tt&gt;
&lt;/tt&gt;                          &lt;span style="color:#036;font-weight:bold"&gt;Base64&lt;/span&gt;.decode64(  &lt;tt&gt;
&lt;/tt&gt;                          &lt;span style="color:#036;font-weight:bold"&gt;URI&lt;/span&gt;.unescape(idForURL))).&lt;tt&gt;
&lt;/tt&gt;                          strip.to_i&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br&gt;
The .ljust(8) is because &lt;a href="http://www.schneier.com/blowfish.html"&gt;Blowfish&lt;/a&gt; is a 64-bit block &lt;a href="http://en.wikipedia.org/wiki/Blowfish_(cipher)"&gt;cipher&lt;/a&gt; and the &lt;a href="http://crypt.rubyforge.org/"&gt;Ruby-implementation&lt;/a&gt; does not pad the data itself.&lt;/p&gt;

&lt;p&gt;The id in the URL in this case would be &lt;code&gt;c2PSXWgky40=&lt;/code&gt;. Its 12 characters long (11 if you skip the equal sign) and that's 10 or 24 characters shorter than a GUID. Also there is zero percent chance of collusion and if you want to you can even decrypt it.&lt;/p&gt;

&lt;p&gt;This is not a super safe implementation but if you start your id's at a random and not too low number you are making it a bit harder for someone to crack the 56-bit key. Actually a truly random and at least 64-bit big number would be a better choice as it would have no connection to the true id at all. You would have to check for uniqueness before storing those in the database though.&lt;/p&gt;</description>
      <pubDate>Thu, 15 Nov 2007 22:38:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:9071a4d1-aaf0-4f17-a796-4ecd65976d64</guid>
      <author>Jonas Elfström</author>
      <link>http://www.alicebobandmallory.com/articles/2007/11/15/blowfish-in-the-url</link>
      <category>Security</category>
      <category>Ruby</category>
      <category>Cryptography</category>
    </item>
    <item>
      <title>The Zodiac Killer Cipher</title>
      <description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Zodiac_Killer"&gt;The Zodiac Killer&lt;/a&gt; was a serial  killer in the late sixties and maybe early seventies. He sent a number of letters to the press, including four ciphers or cryptograms and only one of them has been solved. The killer's identity remains unknown.&lt;/p&gt;

&lt;p&gt;Chris McCarthy has a nice &lt;a href="http://www.dtm.ciw.edu/chris/z/"&gt;page&lt;/a&gt; about the cipher and he also has an &lt;a href="http://www.dtm.ciw.edu/chris/z/340.ascii"&gt;ASCII version&lt;/a&gt; of the cipher.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://alicebobandmallory.com/zodiac.html"&gt;Here's&lt;/a&gt; a small Ruby hack that calculates the character frequency using the &lt;a href="http://www.dtm.ciw.edu/chris/z/340.ascii"&gt;ASCII version&lt;/a&gt; of the cipher. Feel free to use it if you like to have a go at cracking it!&lt;/p&gt;

&lt;p&gt;EDIT: At &lt;a href="http://oranchak.com/zodiac/webtoy/"&gt;this page&lt;/a&gt; you can have a go at cracking it real-time. I am not convinced it's really a &lt;a href="http://en.wikipedia.org/wiki/Substitution_cipher#Homophonic_substitution"&gt;homophonic substition&lt;/a&gt; cipher since the frequency analysis shows that the 340 does not have a flat frequency distribution. &lt;/p&gt;

&lt;p&gt;It would be nice to know what cryptographic literature was available for the public in northern California in the late sixties.&lt;/p&gt;</description>
      <pubDate>Fri, 25 May 2007 18:31:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:4ca66a74-73f3-4ff8-a7d4-c35c39f4db7a</guid>
      <author>Jonas Elfström</author>
      <link>http://www.alicebobandmallory.com/articles/2007/05/25/the-zodiac-killer-crypto</link>
      <category>Ruby</category>
      <category>Cryptography</category>
    </item>
  </channel>
</rss>

