friendica/library/phpsec/sym_crypt.html

119 lines
18 KiB
HTML
Raw Normal View History

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 3. Symmetric-key Cryptography</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="math.html" title="Chapter 2. Math" /><link rel="next" href="misc_crypt.html" title="Chapter 4. Miscellaneous Cryptography" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 3. Symmetric-key Cryptography</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="misc_crypt.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="sym_crypt"></a>Chapter 3. Symmetric-key Cryptography</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_intro">3.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_dependencies">3.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_set">3.1.2. setKey() and setIV()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_encrypt">3.1.3. encrypt() and decrypt()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_continuousbuffer">3.1.4. enableContinuousBuffer() and disableContinuousBuffer()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_padding">3.1.5. enablePadding() and disablePadding()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_caution">3.1.6. A word of caution about stream ciphers and CTR mode</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des">3.2. Crypt_DES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des_constructor">3.2.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes">3.3. Crypt_TripleDES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes_constructor">3.3.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4">3.4. Crypt_RC4</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4_constructor">3.4.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes">3.5. Crypt_Rijndael &amp; Crypt_AES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_constructor">3.5.1. The constructor</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_vs_rijndael">3.5.2. AES vs. Rijndael</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setkeylength">3.5.3. setKeyLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setblocklength">3.5.4. setBlockLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_benchmarks">3.5.5. Speed Comparisons</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_intro"></a>3.1. Introduction</h2></div></div></div><p>
All of the cryptographic libraries included in phpseclib use mcrypt, if available, and an internal implementation
if it's not. The libraries all use a common interface although some functions, for some algorithms, carry with
with them certain caveats. Those that do not have caveats attached (or have relatively few attached) are
described below. If you don't know which one to use, try <code class="code">Crypt_TripleDES</code>.
</p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_dependencies"></a>3.1.1. Dependencies</h3></div></div></div><p>
The Crypt_* functions require, minimally, PHP 4.0.0. Crypt_TripleDES additionally requires Crypt/DES.php.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_set"></a>3.1.2. setKey() and setIV()</h3></div></div></div><p>
Sets the key and the initialization vector, respectively. If neither are set, each assumed to be equal to
some amount of null bytes. The initialization vector is only used in block ciphers and even then only
in CBC mode. If the key or the initialization vector are larger then the block size, they're truncated.
If they're smaller, they're padded with null bytes.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_encrypt"></a>3.1.3. encrypt() and decrypt()</h3></div></div></div><p>
Self-explanatory. Encrypts or decrypts messages. See the examples in the subsequent sections.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_continuousbuffer"></a>3.1.4. enableContinuousBuffer() and disableContinuousBuffer()</h3></div></div></div><p>
If the continuous buffer is enabled and you're using a stream cipher or a block cipher mode other than ECB then encrypting the same string twice will yield different ciphertexts.
The reason being that the IV doesn't reset after each encryption / decryption round when the continuous buffer is used.
This provides better security but it may also make for less intuitive behavior.
For this reason, the continuous buffer is disabled by default.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_padding"></a>3.1.5. enablePadding() and disablePadding()</h3></div></div></div><p>
Enables / disables PKCS padding on block ciphers. Stream ciphers (<code class="code">Crypt_RC4</code> is the only stream
cipher currently included) ignore this.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_caution"></a>3.1.6. A word of caution about stream ciphers and CTR mode</h3></div></div></div><p>
Most stream ciphers (and block ciphers operating in a mode - like CTR - that turns them into stream ciphers) work by generating a stream of pseudorandom characters called a <a class="ulink" href="http://en.wikipedia.org/wiki/Keystream" target="_top">keystream</a> and then XOR'ing that with the plaintext.
This *effectively* makes them <a class="ulink" href="http://en.wikipedia.org/wiki/One-time_pad" target="_top">one-time pads</a> which, in theory, can provide perfect secrecy. The problem with one-time pads is that they're not as versatile as one might desire.
Among other things, a keystream must never be reset, lest it be possible for an attacker to recover the keystream via a <a class="ulink" href="http://en.wikipedia.org/wiki/Known-plaintext_attack" target="_top">known-plaintext attack</a>. ie. <code class="code">$ciphertext ^ $plaintext = $key</code>. If <code class="code">$key</code> is constant (because the keystream's being reset or something) than an attacker can recover any <code class="code">$plaintext</code>, but if not - if it's dynamic - then the only key that an attacker could recover is their own.
</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_des"></a>3.2. Crypt_DES</h2></div></div></div><p>
Implements DES (a block cipher). Here's an example of how to use it:
</p><pre class="programlisting">&lt;?php
include('Crypt/DES.php');
$des = new Crypt_DES();
$des-&gt;setKey('abcdefgh');
$size = 10 * 1024;
$plaintext = '';
for ($i = 0; $i &lt; $size; $i++) {
$plaintext.= 'a';
}
echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_des_constructor"></a>3.2.1. The constructor</h3></div></div></div><p>
The constructor takes one optional parameter - $mode. Valid values for $mode are as follows:
</p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_DES_MODE_ECB</code></li><li><code class="code">CRYPT_DES_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_DES_MODE_CTR</code></li></ul></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_tripledes"></a>3.3. Crypt_TripleDES</h2></div></div></div><p>
Implements TripleDES (a block cipher). Here's an example of how to use it:
</p><pre class="programlisting">&lt;?php
include('Crypt/TripleDES.php');
$des = new Crypt_TripleDES();
$des-&gt;setKey('abcdefghijklmnopqrstuvwx');
$size = 10 * 1024;
$plaintext = '';
for ($i = 0; $i &lt; $size; $i++) {
$plaintext.= 'a';
}
echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_tripledes_constructor"></a>3.3.1. The constructor</h3></div></div></div><p>
The constructor takes one optional parameter - $mode. Valid values for $mode are as follows:
</p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_DES_MODE_ECB</code></li><li><code class="code">CRYPT_DES_MODE_CBC3</code>: Employs outer chaining to propogate the initialization vector. Used by SSH-2 and generally considered more secure than inner chaining.</li><li><code class="code">CRYPT_DES_MODE_3CBC</code>: Employs inner chaining to propogate the initialization vector. Used by SSH-1.</li><li><code class="code">CRYPT_DES_MODE_CBC</code>: The default value. An alias for <code class="code">CRYPT_DES_MODE_CBC3</code>.</li><li><code class="code">CRYPT_DES_MODE_CTR</code></li></ul></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_rc4"></a>3.4. Crypt_RC4</h2></div></div></div><p>
Implements RC4 (a stream cipher). Here's an example of how to use it:
</p><pre class="programlisting">&lt;?php
include('Crypt/RC4.php');
$rc4 = new Crypt_RC4();
$rc4-&gt;setKey('abcdefghijklmnopqrstuvwx');
$size = 10 * 1024;
$plaintext = '';
for ($i = 0; $i &lt; $size; $i++) {
$plaintext.= 'a';
}
echo $rc4-&gt;decrypt($rc4-&gt;encrypt($plaintext));
?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_rc4_constructor"></a>3.4.1. The constructor</h3></div></div></div><p>
Not much to say about this constructor. Since it's a stream cipher, you don't need to worry about which
mode of operation to use.
</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_aes"></a>3.5. Crypt_Rijndael &amp; Crypt_AES</h2></div></div></div><p>
Implements Rijndael / AES. Here's an example of how to use Crypt_AES:
</p><pre class="programlisting">&lt;?php
include('Crypt/AES.php');
$aes = new Crypt_AES();
$aes-&gt;setKey('abcdefghijklmnop');
$size = 10 * 1024;
$plaintext = '';
for ($i = 0; $i &lt; $size; $i++) {
$plaintext.= 'a';
}
echo $aes-&gt;decrypt($aes-&gt;encrypt($plaintext));
?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_constructor"></a>3.5.1. The constructor</h3></div></div></div><p>
<code class="code">Crypt_AES</code>'s constructor's optional parameter can take the following values:
</p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_AES_MODE_ECB</code></li><li><code class="code">CRYPT_AES_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_AES_MODE_CTR</code></li></ul></div><p>
<code class="code">Crypt_Rijndael</code> takes the following:
</p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_RIJNDAEL_MODE_ECB</code></li><li><code class="code">CRYPT_RIJNDAEL_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_RIJNDAEL_MODE_CTR</code></li></ul></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_vs_rijndael"></a>3.5.2. AES vs. Rijndael</h3></div></div></div><p>
AES is a subset of Rijndael. Both have variable key sizes, however, AES's block size is fixed at 128 bits, whereas Rijndael's is variable. Also, Rijndael supports, by means of an extension to the specification, two key sizes that AES does not - 160 bits and 224 bits.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_setkeylength"></a>3.5.3. setKeyLength()</h3></div></div></div><p>
Valid key lengths for AES are 128 bits, 192 bits, and 256 bits. If the key that is assigned is invalid and less than 256 bits, they key length is rounded up to the next closest valid size and the key will be null padded to that amount. If the key length is greater than 256 bits, it will be truncated to 256 bits.
</p><p>
As an example, if the key is 136 bits, it will be null padded to 192 bits (or 160 bits if Rijndael is being used).
</p><p>
If <code class="code">setKeyLength()</code> has been called, this behavior changes somewhat. Say you've set the key length, via this function, to 256 bits. Then, instead of an invalid key being null padded to 192 or 160 bits, it will be null padded to 256 bits.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_setblocklength"></a>3.5.4. setBlockLength()</h3></div></div></div><p>
<code class="code">setBlockLength()</code> operates in a manner similar to <code class="code">setKeyLength()</code>, with one exception. <code class="code">setBlockLength()</code> only works on Rijndael. Although <code class="code">Crypt_AES</code> inherits <code class="code">setBlockLength()</code> as a function, the function doesn't do anything in AES.
</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_benchmarks"></a>3.5.5. Speed Comparisons</h3></div></div></div><p>
The following table compares the speed of five different pure-PHP implementations of AES (one of which is Crypt_Rijndael and one of which is Crypt_AES) when ran on 150KB of text on a 1.8GHz Pentium 4-M. The numbers listed are averaged from five different trials and are measured in seconds. phpseclib's two implementations are highlighted. All implementations can be viewed by clicking on their names.
</p><div class="table"><a id="sym_crypt_aes_benchmarks_table"></a><p class="title"><b>Table 3.1. AES Speed Comparisons</b></p><div class="table-contents"><table summary="AES Speed Comparisons" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/movable-type.phps" target="_top">movable-type.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpaes.phps" target="_top">phpaes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses1.phps" target="_top">phpclasses1.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses2.phps" target="_top">phpclasses2.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-aes.phps" target="_top">phpseclib-aes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-rijndael.phps" target="_top">phpseclib-rijndael.phps</a></th></tr></thead><tbody><tr><td align="right">15.6844158172</td><td align="right">39.9537248135</td><td align="right">15.0100150108</td><td align="right">62.591713190079</td><td class="highlight" align="right">2.03581542968752</td><td class="highlight" align="right">2.62501101493836</td></tr></tbody></table></div></div><br class="table-break" /><p>
As can be seen, phpseclib's implementations are the fastest. phpseclib-aes.phps is faster than phpseclib-rijndael.phps because phpseclib-rijndael.phps has to contend with multiple block sizes whereas phpseclib-aes.phps does not. Note that if mcrypt weren't explicitily disabled phpseclib would have been even faster.
</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="misc_crypt.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Math </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Miscellaneous Cryptography</td></tr></table></div></body></html>