<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged encryption</title>
    <link href="https://passingcuriosity.com/tags/encryption/encryption.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/encryption/encryption.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2009-08-16T00:00:00Z</updated>
    <entry>
    <title>AES encryption in Python with M2Crypto</title>
    <link href="https://passingcuriosity.com/2009/aes-encryption-in-python-with-m2crypto/" />
    <id>https://passingcuriosity.com/2009/aes-encryption-in-python-with-m2crypto/</id>
    <published>2009-08-16T00:00:00Z</published>
    <updated>2009-08-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve needed to write some Python code to handle encryption and decryption
recently. This is a short post describing how I did it.</p>
<p>I’m interacting with a system which encrypts data in transit like so:</p>
<blockquote>
<p>The encryption algorithm is AES with a 16 bit [sic] key. The cipher mode is
CBC with PKCS5 padding. The initialisation vector is 16 bytes of 00.</p>
</blockquote>
<p>Thus I need to handle 128-bit AES in CBC mode, and padding according to PKCS5.
In addition, the key and encrypted data is all base64 encoded.</p>
<p>There are a number of cryptography packages for Python. The first I found was
a blog post describing <a href="http://www.codekoala.com/blog/2009/aes-encryption-python-using-pycrypto/">PyCrypto</a>. My requirements include <a href="http://www.chilkatsoft.com/faq/PKCS5_Padding.html">PKCS5
padding</a>, which PyCrypto doesn’t seem to do. It also has it’s own
implementations of the encryption algorithms.</p>
<p>The padding algorithm seems pretty simple. If I understand correctly, it’d go
something like this in Python:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>pad <span class="op">=</span> <span class="kw">lambda</span> s: s <span class="op">+</span> (BS <span class="op">-</span> <span class="bu">len</span>(s) <span class="op">%</span> BS) <span class="op">*</span> <span class="bu">chr</span>(BS <span class="op">-</span> <span class="bu">len</span>(s) <span class="op">%</span> BS)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>unpad <span class="op">=</span> <span class="kw">lambda</span> s : s[<span class="dv">0</span>:<span class="op">-</span><span class="bu">ord</span>(s[<span class="op">-</span><span class="dv">1</span>])]</span></code></pre></div>
<p>But I’ve got better things to do than convince myself that I’ve implemented it
correctly.</p>
<p>Thankfully, there’s another options: <a href="http://chandlerproject.org/Projects/MeTooCrypto">Me Too Crypto</a>. Unlike
PyCrypto, M2Crypto is a Python wrapper around <a href="http://openssl.org/">OpenSSL</a> which is
nice, as my code will be running under <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> embedded in Apache
along with <a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html">mod_ssl</a>.</p>
<p>Alas, it has rather poor documentation. The best guide to using it I’ve seen
is the <a href="http://svn.osafoundation.org/m2crypto/trunk/tests/">test code</a>. I’m using the EVP interface, and found <code>test_AES()</code>
in the <a href="http://svn.osafoundation.org/m2crypto/trunk/tests/test_evp.py">EVP tests</a> invaluable.</p>
<p>Without further ado, the code:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> base64 <span class="im">import</span> b64encode, b64decode</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> M2Crypto.EVP <span class="im">import</span> Cipher</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>__all__ <span class="op">=</span> [<span class="st">'encryptor'</span>, <span class="st">'decryptor'</span>]</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>ENC<span class="op">=</span><span class="dv">1</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>DEC<span class="op">=</span><span class="dv">0</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> build_cipher(key, iv, op<span class="op">=</span>ENC):</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span><span class="st">&quot;&quot;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Cipher(alg<span class="op">=</span><span class="st">'aes_128_cbc'</span>, key<span class="op">=</span>key, iv<span class="op">=</span>iv, op<span class="op">=</span>op)</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> encryptor(key, iv<span class="op">=</span><span class="va">None</span>):</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="co"># Decode the key and iv</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    key <span class="op">=</span> b64decode(key)</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> iv <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> <span class="st">'</span><span class="ch">\0</span><span class="st">'</span> <span class="op">*</span> <span class="dv">16</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> b64decode(iv)</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>   </span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>   <span class="co"># Return the encryption function</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> encrypt(data):</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>        cipher <span class="op">=</span> build_cipher(key, iv, ENC)</span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> cipher.update(data)</span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> v <span class="op">+</span> cipher.final()</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>        <span class="kw">del</span> cipher</span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> b64encode(v)</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> v</span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> encrypt</span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> decryptor(key, iv<span class="op">=</span><span class="va">None</span>):</span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>    <span class="co"># Decode the key and iv</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>    key <span class="op">=</span> b64decode(key)</span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> iv <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> <span class="st">'</span><span class="ch">\0</span><span class="st">'</span> <span class="op">*</span> <span class="dv">16</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> b64decode(iv)</span>
<span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a>   <span class="co"># Return the decryption function</span></span>
<span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> decrypt(data):</span>
<span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a>        data <span class="op">=</span> b64decode(data)</span>
<span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a>        cipher <span class="op">=</span> build_cipher(key, iv, DEC)</span>
<span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> cipher.update(data)</span>
<span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> v <span class="op">+</span> cipher.final()</span>
<span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a>        <span class="kw">del</span> cipher</span>
<span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> v</span>
<span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> decrypt</span></code></pre></div>]]></summary>
</entry>

</feed>
