python-peps/pep-0272/index.html

357 lines
20 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 272 API for Block Encryption Algorithms v1.0 | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0272/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 272 API for Block Encryption Algorithms v1.0 | peps.python.org'>
<meta property="og:description" content="This document specifies a standard API for secret-key block encryption algorithms such as DES or Rijndael, making it easier to switch between different algorithms and implementations.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0272/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="This document specifies a standard API for secret-key block encryption algorithms such as DES or Rijndael, making it easier to switch between different algorithms and implementations.">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 272</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 272 API for Block Encryption Algorithms v1.0</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">A.M. Kuchling &lt;amk&#32;&#97;t&#32;amk.ca&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">18-Sep-2001</dd>
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
<dd class="field-odd">17-Apr-2002, 29-May-2002</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#changes">Changes</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This document specifies a standard API for secret-key block
encryption algorithms such as DES or Rijndael, making it easier to
switch between different algorithms and implementations.</p>
</section>
<section id="introduction">
<h2><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h2>
<p>Encryption algorithms transform their input data (called
plaintext) in some way that is dependent on a variable key,
producing ciphertext. The transformation can easily be reversed
if and only if one knows the key. The key is a sequence of bits
chosen from some very large space of possible keys. There are two
classes of encryption algorithms: block ciphers and stream ciphers.</p>
<p>Block ciphers encrypt multibyte inputs of a fixed size (frequently
8 or 16 bytes long), and can be operated in various feedback
modes. The feedback modes supported in this specification are:</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Number</th>
<th class="head">Constant</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td>1</td>
<td>MODE_ECB</td>
<td>Electronic Code Book</td>
</tr>
<tr class="row-odd"><td>2</td>
<td>MODE_CBC</td>
<td>Cipher Block Chaining</td>
</tr>
<tr class="row-even"><td>3</td>
<td>MODE_CFB</td>
<td>Cipher Feedback</td>
</tr>
<tr class="row-odd"><td>5</td>
<td>MODE_OFB</td>
<td>Output Feedback</td>
</tr>
<tr class="row-even"><td>6</td>
<td>MODE_CTR</td>
<td>Counter</td>
</tr>
</tbody>
</table>
<p>These modes are to be implemented as described in NIST publication
SP 800-38A <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a>. Descriptions of the first three feedback modes can
also be found in Bruce Schneiers book <em>Applied Cryptography</em> <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>.</p>
<p>(The numeric value 4 is reserved for MODE_PGP, a variant of CFB
described in <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2440.html"><strong>RFC 2440</strong></a>: “OpenPGP Message Format”. This mode
isnt considered important enough to make it worth requiring it
for all block encryption ciphers, though supporting it is a nice
extra feature.)</p>
<p>In a strict formal sense, stream ciphers encrypt data bit-by-bit;
practically, stream ciphers work on a character-by-character
basis. This PEP only aims at specifying an interface for block
ciphers, though stream ciphers can support the interface described
here by fixing block_size to 1. Feedback modes also dont make
sense for stream ciphers, so the only reasonable feedback mode
would be ECB mode.</p>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<p>Encryption modules can add additional functions, methods, and
attributes beyond those described in this PEP, but all of the
features described in this PEP must be present for a module to
claim compliance with it.</p>
<p>Secret-key encryption modules should define one function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="p">[</span><span class="n">IV</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</pre></div>
</div>
<p>Returns a ciphering object, using the secret key contained in the
string key, and using the feedback mode mode, which must be
one of the constants from the table above.</p>
<p>If mode is MODE_CBC or MODE_CFB, IV must be provided and must
be a string of the same length as the block size. Not providing a
value of IV will result in a <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> exception being raised.</p>
<p>Depending on the algorithm, a module may support additional
keyword arguments to this function. Some keyword arguments are
specified by this PEP, and modules are free to add additional
keyword arguments. If a value isnt provided for a given keyword,
a secure default value should be used. For example, if an
algorithm has a selectable number of rounds between 1 and 16, and
1-round encryption is insecure and 8-round encryption is believed
secure, the default value for rounds should be 8 or more.
(Module implementors can choose a very slow but secure value, too,
such as 16 in this example. This decision is left up to the
implementor.)</p>
<p>The following table lists keyword arguments defined by this PEP:</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Keyword</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td>counter</td>
<td>Callable object that returns counter blocks
(see below; CTR mode only)</td>
</tr>
<tr class="row-odd"><td>rounds</td>
<td>Number of rounds of encryption to use</td>
</tr>
<tr class="row-even"><td>segment_size</td>
<td>Size of data and ciphertext segments,
measured in bits (see below; CFB mode only)</td>
</tr>
</tbody>
</table>
<p>The Counter feedback mode requires a sequence of input blocks,
called counters, that are used to produce the output. When mode
is MODE_CTR, the counter keyword argument must be provided, and
its value must be a callable object, such as a function or method.
Successive calls to this callable object must return a sequence of
strings that are of the length block_size and that never
repeats. (Appendix B of the NIST publication gives a way to
generate such a sequence, but thats beyond the scope of this
PEP.)</p>
<p>The CFB mode operates on segments of the plaintext and ciphertext
that are segment_size bits long. Therefore, when using this
mode, the input and output strings must be a multiple of
segment_size bits in length. segment_size must be an integer
between 1 and block_size*8, inclusive. (The factor of 8 comes
from block_size being measured in bytes and not in bits). The
default value for this parameter should be block_size*8.
Implementors are allowed to constrain segment_size to be a
multiple of 8 for simplicity, but theyre encouraged to support
arbitrary values for generality.</p>
<p>Secret-key encryption modules should define two variables:</p>
<ul>
<li>block_size<p>An integer value; the size of the blocks encrypted by this
module, measured in bytes. For all feedback modes, the length
of strings passed to the encrypt() and decrypt() must be a
multiple of the block size.</p>
</li>
<li>key_size<p>An integer value; the size of the keys required by this
module, measured in bytes. If key_size is None, then the
algorithm accepts variable-length keys. This may mean the
module accepts keys of any random length, or that there are a
few different possible lengths, e.g. 16, 24, or 32 bytes. You
cannot pass a key of length 0 (that is, the null string ) as
a variable-length key.</p>
</li>
</ul>
<p>Cipher objects should have two attributes:</p>
<ul>
<li>block_size<p>An integer value equal to the size of the blocks encrypted by
this object. For algorithms with a variable block size, this
value is equal to the block size selected for this object.</p>
</li>
<li>IV<p>Contains the initial value which will be used to start a
cipher feedback mode; it will always be a string exactly one
block in length. After encrypting or decrypting a string,
this value is updated to reflect the modified feedback text.
It is read-only, and cannot be assigned a new value.</p>
</li>
</ul>
<p>Cipher objects require the following methods:</p>
<ul>
<li>decrypt(string)<p>Decrypts string, using the key-dependent data in the object
and with the appropriate feedback mode. The strings length
must be an exact multiple of the algorithms block size or, in
CFB mode, of the segment size. Returns a string containing
the plaintext.</p>
</li>
<li>encrypt(string)<p>Encrypts a non-empty string, using the key-dependent data in
the object, and with the appropriate feedback mode. The
strings length must be an exact multiple of the algorithms
block size or, in CFB mode, of the segment size. Returns a
string containing the ciphertext.</p>
</li>
</ul>
<p>Heres an example, using a module named DES:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">DES</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">DES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;abcdefgh&#39;</span><span class="p">,</span> <span class="n">DES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">plaintext</span> <span class="o">=</span> <span class="s2">&quot;Guido van Rossum is a space alien.&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">plaintext</span><span class="p">)</span>
<span class="go">34</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">plaintext</span><span class="p">)</span>
<span class="go">Traceback (innermost last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">?</span>
<span class="gr">ValueError</span>: <span class="n">Strings for DES must be a multiple of 8 in length</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ciphertext</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">plain</span><span class="o">+</span><span class="s1">&#39;XXXXXX&#39;</span><span class="p">)</span> <span class="c1"># Add padding</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ciphertext</span>
<span class="go">&#39;\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">ciphertext</span><span class="p">)</span>
<span class="go">&#39;Guido van Rossum is a space alien.XXXXXX&#39;</span>
</pre></div>
</div>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id3" role="doc-footnote">
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
<dd>NIST publication SP 800-38A, “Recommendation for Block Cipher
Modes of Operation” (<a class="reference external" href="http://csrc.nist.gov/encryption/modes/">http://csrc.nist.gov/encryption/modes/</a>)</aside>
<aside class="footnote brackets" id="id4" role="doc-footnote">
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
<dd>Applied Cryptography</aside>
</aside>
</section>
<section id="changes">
<h2><a class="toc-backref" href="#changes" role="doc-backlink">Changes</a></h2>
<p>2002-04: Removed references to stream ciphers; retitled PEP;
prefixed feedback mode constants with <code class="docutils literal notranslate"><span class="pre">MODE_</span></code>; removed PGP feedback
mode; added CTR and OFB feedback modes; clarified where numbers
are measured in bytes and where in bits.</p>
<p>2002-09: Clarified the discussion of key length by using
“variable-length keys” instead of “arbitrary-length”.</p>
</section>
<section id="acknowledgements">
<h2><a class="toc-backref" href="#acknowledgements" role="doc-backlink">Acknowledgements</a></h2>
<p>Thanks to the readers of the python-crypto list for their comments on
this PEP.</p>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0272.rst">https://github.com/python/peps/blob/main/peps/pep-0272.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0272.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#changes">Changes</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0272.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>