1 2 3<!DOCTYPE html> 4<html class="writer-html5" lang="en" data-content_root="../"> 5<head> 6 <meta charset="utf-8" /> 7 <meta name="readthedocs-addons-api-version" content="1"><meta name="viewport" content="width=device-width, initial-scale=1" /> 8 9 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 10 <title>Fernet (symmetric encryption) — Cryptography 51.0.0-dev1 documentation</title> 11 <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=03e43079" /> 12 <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=9edc463e" /> 13 <link rel="stylesheet" type="text/css" href="../_static/tabs.css?v=4c969af8" /> 14 15 16
16<script src="../_static/jquery.js?v=5d32c60e"></script>
16 17
17<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
17 18
18<script src="../_static/documentation_options.js?v=6bfd0e6c"></script>
18 19
19<script src="../_static/doctools.js?v=fd6eb6e6"></script>
19 20
20<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
20 21
21<script src="../_static/tabs.js?v=3ee01567"></script>
21 22
22<script src="../_static/js/theme.js"></script>
22 23
23<script src="../_static/js/versions.js"></script>
23 24 <link rel="index" title="Index" href="../genindex/" /> 25 <link rel="search" title="Search" href="../search/" /> 26 <link rel="next" title="Cobblestone (streaming symmetric encryption)" href="../cobblestone/" /> 27 <link rel="prev" title="Welcome to pyca/cryptography" href="../" />
28<script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script>
28<meta name="readthedocs-project-slug" content="cryptography" /><meta name="readthedocs-version-slug" content="latest" /><meta name="readthedocs-resolver-filename" content="/fernet/" /><meta name="readthedocs-http-status" content="200" /></head> 29 30<body class="wy-body-for-nav"> 31 <div class="wy-grid-for-nav"> 32 <nav data-toggle="wy-nav-shift" class="wy-nav-side"> 33 <div class="wy-side-scroll"> 34 <div class="wy-side-nav-search" > 35 36 37 38 39 <a href="../" class="icon icon-home"> 40 Cryptography 41 </a> 42 <div class="switch-menus"> 43 <div class="version-switch"></div> 44 <div class="language-switch"></div> 45 </div> 46<div role="search"> 47 <form id="rtd-search-form" class="wy-form" action="../search/" method="get"> 48 <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> 49 <input type="hidden" name="check_keywords" value="yes" /> 50 <input type="hidden" name="area" value="default" /> 51 </form> 52</div> 53<a href="https://github.com/pyca/cryptography" style="display:block;margin-top:8px;text-align:center;">View on GitHub</a> 54 55 </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> 56 <p class="caption" role="heading"><span class="caption-text">The recipes layer</span></p> 57<ul class="current"> 58<li class="toctree-l1 current"><a class="current reference internal" href="#">Fernet (symmetric encryption)</a><ul> 59<li class="toctree-l2"><a class="reference internal" href="#cryptography.fernet.Fernet"><code class="docutils literal notranslate"><span class="pre">Fernet</span></code></a><ul> 60<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.generate_key"><code class="docutils literal notranslate"><span class="pre">Fernet.generate_key()</span></code></a></li> 61<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.encrypt"><code class="docutils literal notranslate"><span class="pre">Fernet.encrypt()</span></code></a></li> 62<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.encrypt_at_time"><code class="docutils literal notranslate"><span class="pre">Fernet.encrypt_at_time()</span></code></a></li> 63<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.decrypt"><code class="docutils literal notranslate"><span class="pre">Fernet.decrypt()</span></code></a></li> 64<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.decrypt_at_time"><code class="docutils literal notranslate"><span class="pre">Fernet.decrypt_at_time()</span></code></a></li> 65<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.Fernet.extract_timestamp"><code class="docutils literal notranslate"><span class="pre">Fernet.extract_timestamp()</span></code></a></li> 66</ul> 67</li> 68<li class="toctree-l2"><a class="reference internal" href="#cryptography.fernet.MultiFernet"><code class="docutils literal notranslate"><span class="pre">MultiFernet</span></code></a><ul> 69<li class="toctree-l3"><a class="reference internal" href="#cryptography.fernet.MultiFernet.rotate"><code class="docutils literal notranslate"><span class="pre">MultiFernet.rotate()</span></code></a></li> 70</ul> 71</li> 72<li class="toctree-l2"><a class="reference internal" href="#cryptography.fernet.InvalidToken"><code class="docutils literal notranslate"><span class="pre">InvalidToken</span></code></a></li> 73<li class="toctree-l2"><a class="reference internal" href="#using-passwords-with-fernet">Using passwords with Fernet</a></li> 74<li class="toctree-l2"><a class="reference internal" href="#implementation">Implementation</a></li> 75<li class="toctree-l2"><a class="reference internal" href="#limitations">Limitations</a></li> 76</ul> 77</li> 78<li class="toctree-l1"><a class="reference internal" href="../cobblestone/">Cobblestone (streaming symmetric encryption)</a></li> 79<li class="toctree-l1"><a class="reference internal" href="../x509/">X.509</a></li> 80</ul> 81<p class="caption" role="heading"><span class="caption-text">The hazardous materials layer</span></p> 82<ul> 83<li class="toctree-l1"><a class="reference internal" href="../hazmat/primitives/">Primitives</a></li> 84<li class="toctree-l1"><a class="reference internal" href="../exceptions/">Exceptions</a></li> 85<li class="toctree-l1"><a class="reference internal" href="../random-numbers/">Random number generation</a></li> 86<li class="toctree-l1"><a class="reference internal" href="../hazmat/asn1/">ASN.1</a></li> 87<li class="toctree-l1"><a class="reference internal" href="../hazmat/decrepit/">Decrepit cryptography</a></li> 88</ul> 89<p class="caption" role="heading"><span class="caption-text">The cryptography open source project</span></p> 90<ul> 91<li class="toctree-l1"><a class="reference internal" href="../installation/">Installation</a></li> 92<li class="toctree-l1"><a class="reference internal" href="../changelog/">Changelog</a></li> 93<li class="toctree-l1"><a class="reference internal" href="../faq/">Frequently asked questions</a></li> 94<li class="toctree-l1"><a class="reference internal" href="../development/">Development</a></li> 95<li class="toctree-l1"><a class="reference internal" href="../openssl/">Use of OpenSSL</a></li> 96<li class="toctree-l1"><a class="reference internal" href="../security/">Security</a></li> 97<li class="toctree-l1"><a class="reference internal" href="../limitations/">Known security limitations</a></li> 98<li class="toctree-l1"><a class="reference internal" href="../api-stability/">API stability</a></li> 99<li class="toctree-l1"><a class="reference internal" href="../doing-a-release/">Doing a release</a></li> 100<li class="toctree-l1"><a class="reference internal" href="../community/">Community</a></li> 101<li class="toctree-l1"><a class="reference internal" href="../glossary/">Glossary</a></li> 102</ul> 103<ul> 104<li class="toctree-l1"><a class="reference internal" href="../statements/">Statements</a></li> 105</ul> 106 107 </div> 108 </div> 109 </nav> 110 111 <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > 112 <i data-toggle="wy-nav-top" class="fa fa-bars"></i> 113 <a href="../">Cryptography</a> 114 </nav> 115 116 <div class="wy-nav-content"> 117 <div class="rst-content"> 118 <div role="navigation" aria-label="Page navigation"> 119 <ul class="wy-breadcrumbs"> 120 <li><a href="../" class="icon icon-home" aria-label="Home"></a></li> 121 <li class="breadcrumb-item active">Fernet (symmetric encryption)</li> 122 <li class="wy-breadcrumbs-aside"> 123 <a href="../_sources/fernet.rst.txt" rel="nofollow"> View page source</a> 124 </li> 125 </ul> 126 <hr/> 127</div> 128 <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> 129 <div itemprop="articleBody"> 130 131 <section id="fernet-symmetric-encryption"> 132<h1>Fernet (symmetric encryption)<a class="headerlink" href="#fernet-symmetric-encryption" title="Link to this heading">ï</a></h1> 133<p>Fernet guarantees that a message encrypted using it cannot be 134manipulated or read without the key. <a class="reference external" href="https://github.com/fernet/spec/">Fernet</a> is an implementation of 135symmetric (also known as âsecret keyâ) authenticated cryptography. Fernet also 136has support for implementing key rotation via <a class="reference internal" href="#cryptography.fernet.MultiFernet" title="cryptography.fernet.MultiFernet"><code class="xref py py-class docutils literal notranslate"><span class="pre">MultiFernet</span></code></a>.</p> 137<dl class="py class"> 138<dt class="sig sig-object py" id="cryptography.fernet.Fernet"> 139<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">cryptography.fernet.</span></span><span class="sig-name descname"><span class="pre">Fernet</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">key</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet" title="Link to this definition">ï</a></dt> 140<dd><p>This class provides both encryption and decryption facilities. This class 141exhibits <a class="reference internal" href="../glossary/#term-thread-safety"><span class="xref std std-term">thread safety</span></a>.</p> 142<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.fernet</span><span class="w"> </span><span class="kn">
142import</span> <span class="n">Fernet</span> 143<span class="gp">>>> </span><span class="n">key</span> <span class="o">=</span> <span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">()</span> 144<span class="gp">>>> </span><span class="n">f</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> 145<span class="gp">>>> </span><span class="n">token</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="sa">b</span><span class="s2">"my deep dark secret"</span><span class="p">)</span> 146<span class="gp">>>> </span><span class="n">token</span> 147<span class="go">b'...'</span> 148<span class="gp">>>> </span><span class="n">f</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">token</span><span class="p">)</span> 149<span class="go">b'my deep dark secret'</span> 150</pre></div> 151</div> 152<dl class="field-list simple"> 153<dt class="field-odd">Parameters<span class="colon">:</span></dt> 154<dd class="field-odd"><p><strong>key</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#bytes" title="(in Python v3.14)"><em>bytes</em></a><em> or </em><a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#str" title="(in Python v3.14)"><em>str</em></a>) â A URL-safe base64-encoded 32-byte key. This <strong>must</strong> be 155kept secret. Anyone with this key is able to create and 156read messages.</p> 157</dd> 158</dl> 159<dl class="py method"> 160<dt class="sig sig-object py" id="cryptography.fernet.Fernet.generate_key"> 161<span class="property"><span class="k"><span class="pre">classmethod</span></span><span class="w"> </span></span><span class="sig-name descname"><span class="pre">generate_key</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.generate_key" title="Link to this definition">ï</a></dt> 162<dd><p>Generates a fresh fernet key. Keep this some place safe! If you lose it 163youâll no longer be able to decrypt messages; if anyone else gains 164access to it, theyâll be able to decrypt all of your messages, and 165theyâll also be able to forge arbitrary messages that will be 166authenticated and decrypted.</p> 167</dd></dl> 168 169<dl class="py method"> 170<dt class="sig sig-object py" id="cryptography.fernet.Fernet.encrypt"> 171<span class="sig-name descname"><span class="pre">encrypt</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.encrypt" title="Link to this definition">ï</a></dt> 172<dd><p>Encrypts data passed. The result of this encryption is known as a 173âFernet tokenâ and has strong privacy and authenticity guarantees.</p> 174<dl class="field-list simple"> 175<dt class="field-odd">Parameters<span class="colon">:</span></dt> 176<dd class="field-odd"><p><strong>data</strong> (<a class="reference internal" href="../glossary/#term-bytes-like"><span class="xref std std-term">bytes-like</span></a>) â The message you would like to encrypt.</p> 177</dd> 178<dt class="field-even">Returns bytes<span class="colon">:</span></dt> 179<dd class="field-even"><p>A secure message that cannot be read or altered 180without the key. It is URL-safe base64-encoded. This is 181referred to as a âFernet tokenâ.</p> 182</dd> 183<dt class="field-odd">Raises<span class="colon">:</span></dt> 184<dd class="field-odd"><p><a class="reference external" href="https://docs.python.org/3/builtins/exceptions.html#TypeError" title="(in Python v3.14)"><strong>TypeError</strong></a> â This exception is raised if <code class="docutils literal notranslate"><span class="pre">data</span></code> is not 185<a class="reference internal" href="../glossary/#term-bytes-like"><span class="xref std std-term">bytes-like</span></a>.</p> 186</dd> 187</dl> 188<div class="admonition note"> 189<p class="admonition-title">Note</p> 190<p>The encrypted message contains the current time when it was 191generated in <em>plaintext</em>, the time a message was created will 192therefore be visible to a possible attacker.</p> 193</div> 194</dd></dl> 195 196<dl class="py method"> 197<dt class="sig sig-object py" id="cryptography.fernet.Fernet.encrypt_at_time"> 198<span class="sig-name descname"><span class="pre">encrypt_at_time</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">current_time</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.encrypt_at_time" title="Link to this definition">ï</a></dt> 199<dd><div class="versionadded"> 200<p><span class="versionmodified added">Added in version 3.0.</span></p> 201</div> 202<p>Encrypts data passed using explicitly passed current time. See 203<a class="reference internal" href="#cryptography.fernet.Fernet.encrypt" title="cryptography.fernet.Fernet.encrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">encrypt()</span></code></a> for the documentation of the <code class="docutils literal notranslate"><span class="pre">data</span></code> parameter, the 204return type and the exceptions raised.</p> 205<p>The motivation behind this method is for the client code to be able to 206test token expiration. Since this method can be used in an insecure 207manner one should make sure the correct time (<code class="docutils literal notranslate"><span class="pre">int(time.time())</span></code>) 208is passed as <code class="docutils literal notranslate"><span class="pre">current_time</span></code> outside testing.</p> 209<dl class="field-list simple"> 210<dt class="field-odd">Parameters<span class="colon">:</span></dt> 211<dd class="field-odd"><p><strong>current_time</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/functions.html#int" title="(in Python v3.14)"><em>int</em></a>) â The current time.</p> 212</dd> 213</dl> 214<div class="admonition note"> 215<p class="admonition-title">Note</p> 216<p>Similarly to <a class="reference internal" href="#cryptography.fernet.Fernet.encrypt" title="cryptography.fernet.Fernet.encrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">encrypt()</span></code></a> the encrypted message contains the 217timestamp in <em>plaintext</em>, in this case the timestamp is the value 218of the <code class="docutils literal notranslate"><span class="pre">current_time</span></code> parameter.</p> 219</div> 220</dd></dl> 221 222<dl class="py method"> 223<dt class="sig sig-object py" id="cryptography.fernet.Fernet.decrypt"> 224<span class="sig-name descname"><span class="pre">decrypt</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">token</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">ttl</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.decrypt" title="Link to this definition">ï</a></dt> 225<dd><p>Decrypts a Fernet token. If successfully decrypted you will receive the 226original plaintext as the result, otherwise an exception will be 227raised. It is safe to use this data immediately as Fernet verifies 228that the data has not been tampered with prior to returning it.</p> 229<dl class="field-list simple"> 230<dt class="field-odd">Parameters<span class="colon">:</span></dt> 231<dd class="field-odd"><ul class="simple"> 232<li><p><strong>token</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#bytes" title="(in Python v3.14)"><em>bytes</em></a><em> or </em><a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#str" title="(in Python v3.14)"><em>str</em></a>) â The Fernet token. This is the result of 233calling <a class="reference internal" href="#cryptography.fernet.Fernet.encrypt" title="cryptography.fernet.Fernet.encrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">encrypt()</span></code></a>.</p></li> 234<li><p><strong>ttl</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/functions.html#int" title="(in Python v3.14)"><em>int</em></a>) â Optionally, the number of seconds old a message may be 235for it to be valid. If the message is older than 236<code class="docutils literal notranslate"><span class="pre">ttl</span></code> seconds (from the time it was originally 237created) an exception will be raised. If <code class="docutils literal notranslate"><span class="pre">ttl</span></code> is not 238provided (or is <code class="docutils literal notranslate"><span class="pre">None</span></code>), the age of the message is 239not considered.</p></li> 240</ul> 241</dd> 242<dt class="field-even">Returns bytes<span class="colon">:</span></dt> 243<dd class="field-even"><p>The original plaintext.</p> 244</dd> 245<dt class="field-odd">Raises<span class="colon">:</span></dt> 246<dd class="field-odd"><ul class="simple"> 247<li><p><a class="reference internal" href="#cryptography.fernet.InvalidToken" title="cryptography.fernet.InvalidToken"><strong>cryptography.fernet.InvalidToken</strong></a> â If the <code class="docutils literal notranslate"><span class="pre">token</span></code> is in any
248way invalid, this exception 249is raised. A token may be 250invalid for a number of 251reasons: it is older than the 252<code class="docutils literal notranslate"><span class="pre">ttl</span></code>, it is malformed, or 253it does not have a valid 254signature.</p></li> 255<li><p><a class="reference external" href="https://docs.python.org/3/builtins/exceptions.html#TypeError" title="(in Python v3.14)"><strong>TypeError</strong></a> â This exception is raised if <code class="docutils literal notranslate"><span class="pre">token</span></code> is not 256<code class="docutils literal notranslate"><span class="pre">bytes</span></code> or <code class="docutils literal notranslate"><span class="pre">str</span></code>.</p></li> 257</ul> 258</dd> 259</dl> 260</dd></dl> 261 262<dl class="py method"> 263<dt class="sig sig-object py" id="cryptography.fernet.Fernet.decrypt_at_time"> 264<span class="sig-name descname"><span class="pre">decrypt_at_time</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">token</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">ttl</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">current_time</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.decrypt_at_time" title="Link to this definition">ï</a></dt> 265<dd><div class="versionadded"> 266<p><span class="versionmodified added">Added in version 3.0.</span></p> 267</div> 268<p>Decrypts a token using explicitly passed current time. See 269<a class="reference internal" href="#cryptography.fernet.Fernet.decrypt" title="cryptography.fernet.Fernet.decrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">decrypt()</span></code></a> for the documentation of the <code class="docutils literal notranslate"><span class="pre">token</span></code> and <code class="docutils literal notranslate"><span class="pre">ttl</span></code> 270parameters (<code class="docutils literal notranslate"><span class="pre">ttl</span></code> is required here), the return type and the exceptions 271raised.</p> 272<p>The motivation behind this method is for the client code to be able to 273test token expiration. Since this method can be used in an insecure 274manner one should make sure the correct time (<code class="docutils literal notranslate"><span class="pre">int(time.time())</span></code>) 275is passed as <code class="docutils literal notranslate"><span class="pre">current_time</span></code> outside testing.</p> 276<dl class="field-list simple"> 277<dt class="field-odd">Parameters<span class="colon">:</span></dt> 278<dd class="field-odd"><p><strong>current_time</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/functions.html#int" title="(in Python v3.14)"><em>int</em></a>) â The current time.</p> 279</dd> 280</dl> 281</dd></dl> 282 283<dl class="py method"> 284<dt class="sig sig-object py" id="cryptography.fernet.Fernet.extract_timestamp"> 285<span class="sig-name descname"><span class="pre">extract_timestamp</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">token</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.Fernet.extract_timestamp" title="Link to this definition">ï</a></dt> 286<dd><div class="versionadded"> 287<p><span class="versionmodified added">Added in version 2.3.</span></p> 288</div> 289<p>Returns the timestamp for the token. The caller can then decide if 290the token is about to expire and, for example, issue a new token.</p> 291<dl class="field-list simple"> 292<dt class="field-odd">Parameters<span class="colon">:</span></dt> 293<dd class="field-odd"><p><strong>token</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#bytes" title="(in Python v3.14)"><em>bytes</em></a><em> or </em><a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#str" title="(in Python v3.14)"><em>str</em></a>) â The Fernet token. This is the result of 294calling <a class="reference internal" href="#cryptography.fernet.Fernet.encrypt" title="cryptography.fernet.Fernet.encrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">encrypt()</span></code></a>.</p> 295</dd> 296<dt class="field-even">Returns int<span class="colon">:</span></dt> 297<dd class="field-even"><p>The Unix timestamp of the token.</p> 298</dd> 299<dt class="field-odd">Raises<span class="colon">:</span></dt> 300<dd class="field-odd"><ul class="simple"> 301<li><p><a class="reference internal" href="#cryptography.fernet.InvalidToken" title="cryptography.fernet.InvalidToken"><strong>cryptography.fernet.InvalidToken</strong></a> â If the <code class="docutils literal notranslate"><span class="pre">token</span></code>âs signature
302is invalid this exception 303is raised.</p></li> 304<li><p><a class="reference external" href="https://docs.python.org/3/builtins/exceptions.html#TypeError" title="(in Python v3.14)"><strong>TypeError</strong></a> â This exception is raised if <code class="docutils literal notranslate"><span class="pre">token</span></code> is not 305<code class="docutils literal notranslate"><span class="pre">bytes</span></code> or <code class="docutils literal notranslate"><span class="pre">str</span></code>.</p></li> 306</ul> 307</dd> 308</dl> 309</dd></dl> 310 311</dd></dl> 312 313<dl class="py class"> 314<dt class="sig sig-object py" id="cryptography.fernet.MultiFernet"> 315<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">cryptography.fernet.</span></span><span class="sig-name descname"><span class="pre">MultiFernet</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">fernets</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.MultiFernet" title="Link to this definition">ï</a></dt> 316<dd><div class="versionadded"> 317<p><span class="versionmodified added">Added in version 0.7.</span></p> 318</div> 319<p>This class implements key rotation for Fernet. It takes a <code class="docutils literal notranslate"><span class="pre">list</span></code> of 320<a class="reference internal" href="#cryptography.fernet.Fernet" title="cryptography.fernet.Fernet"><code class="xref py py-class docutils literal notranslate"><span class="pre">Fernet</span></code></a> instances and implements the same API with the exception 321of one additional method: <a class="reference internal" href="#cryptography.fernet.MultiFernet.rotate" title="cryptography.fernet.MultiFernet.rotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">MultiFernet.rotate()</span></code></a>:</p> 322<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.fernet</span><span class="w"> </span><span class="kn">import</span> <span class="n">Fernet</span><span class="p">,</span> <span class="n">MultiFernet</span> 323<span class="gp">>>> </span><span class="n">key1</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">())</span> 324<span class="gp">>>> </span><span class="n">key2</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">())</span> 325<span class="gp">>>> </span><span class="n">f</span> <span class="o">=</span> <span class="n">MultiFernet</span><span class="p">([</span><span class="n">key1</span><span class="p">,</span> <span class="n">key2</span><span class="p">])</span> 326<span class="gp">>>> </span><span class="n">token</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="sa">b</span><span class="s2">"Secret message!"</span><span class="p">)</span> 327<span class="gp">>>> </span><span class="n">token</span> 328<span class="go">b'...'</span> 329<span class="gp">>>> </span><span class="n">f</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">token</span><span class="p">)</span> 330<span class="go">b'Secret message!'</span> 331</pre></div> 332</div> 333<p>MultiFernet performs all encryption options using the <em>first</em> key in the 334<code class="docutils literal notranslate"><span class="pre">list</span></code> provided. MultiFernet attempts to decrypt tokens with each key in 335turn. A <a class="reference internal" href="#cryptography.fernet.InvalidToken" title="cryptography.fernet.InvalidToken"><code class="xref py py-class docutils literal notranslate"><span class="pre">cryptography.fernet.InvalidToken</span></code></a> exception is raised if 336the correct key is not found in the <code class="docutils literal notranslate"><span class="pre">list</span></code>
336 provided.</p> 337<p>Key rotation makes it easy to replace old keys. You can add your new key at 338the front of the list to start encrypting new messages, and remove old keys 339as they are no longer needed.</p> 340<p>Token rotation as offered by <a class="reference internal" href="#cryptography.fernet.MultiFernet.rotate" title="cryptography.fernet.MultiFernet.rotate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">MultiFernet.rotate()</span></code></a> is a best practice 341and manner of cryptographic hygiene designed to limit damage in the event of 342an undetected event and to increase the difficulty of attacks. For example, 343if an employee who had access to your companyâs fernet keys leaves, youâll 344want to generate new fernet key, rotate all of the tokens currently deployed 345using that new key, and then retire the old fernet key(s) to which the 346employee had access.</p> 347<dl class="py method"> 348<dt class="sig sig-object py" id="cryptography.fernet.MultiFernet.rotate"> 349<span class="sig-name descname"><span class="pre">rotate</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">msg</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#cryptography.fernet.MultiFernet.rotate" title="Link to this definition">ï</a></dt> 350<dd><div class="versionadded"> 351<p><span class="versionmodified added">Added in version 2.2.</span></p> 352</div> 353<p>Rotates a token by re-encrypting it under the <a class="reference internal" href="#cryptography.fernet.MultiFernet" title="cryptography.fernet.MultiFernet"><code class="xref py py-class docutils literal notranslate"><span class="pre">MultiFernet</span></code></a> 354instanceâs primary key. This preserves the timestamp that was originally 355saved with the token. If a token has successfully been rotated then the 356rotated token will be returned. If rotation fails this will raise an 357exception.</p> 358<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.fernet</span><span class="w"> </span><span class="kn">import</span> <span class="n">Fernet</span><span class="p">,</span> <span class="n">MultiFernet</span> 359<span class="gp">>>> </span><span class="n">key1</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">())</span> 360<span class="gp">>>> </span><span class="n">key2</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">())</span> 361<span class="gp">>>> </span><span class="n">f</span> <span class="o">=</span> <span class="n">MultiFernet</span><span class="p">([</span><span class="n">key1</span><span class="p">,</span> <span class="n">key2</span><span class="p">])</span> 362<span class="gp">>>> </span><span class="n">token</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="sa">b</span><span class="s2">"Secret message!"</span><span class="p">)</span> 363<span class="gp">>>> </span><span class="n">token</span> 364<span class="go">b'...'</span> 365<span class="gp">>>> </span><span class="n">f</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">token</span><span class="p">)</span> 366<span class="go">b'Secret message!'</span> 367<span class="gp">>>> </span><span class="n">key3</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">Fernet</span><span class="o">.</span><span class="n">generate_key</span><span class="p">())</span> 368<span class="gp">>>> </span><span class="n">f2</span> <span class="o">=</span> <span class="n">MultiFernet</span><span class="p">([</span><span class="n">key3</span><span class="p">,</span> <span class="n">key1</span><span class="p">,</span> <span class="n">key2</span><span class="p">])</span> 369<span class="gp">>>> </span><span class="n">rotated</span> <span class="o">=</span> <span class="n">f2</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="n">token</span><span class="p">)</span> 370<span class="gp">>>> </span><span class="n">f2</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">rotated</span><span class="p">)</span> 371<span class="go">
371b'Secret message!'</span> 372</pre></div> 373</div> 374<dl class="field-list simple"> 375<dt class="field-odd">Parameters<span class="colon">:</span></dt> 376<dd class="field-odd"><p><strong>msg</strong> (<a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#bytes" title="(in Python v3.14)"><em>bytes</em></a><em> or </em><a class="reference external" href="https://docs.python.org/3/builtins/stdtypes.html#str" title="(in Python v3.14)"><em>str</em></a>) â The token to re-encrypt.</p> 377</dd> 378<dt class="field-even">Returns bytes<span class="colon">:</span></dt> 379<dd class="field-even"><p>A secure message that cannot be read or altered without 380the key. This is URL-safe base64-encoded. This is referred to as a 381âFernet tokenâ.</p> 382</dd> 383<dt class="field-odd">Raises<span class="colon">:</span></dt> 384<dd class="field-odd"><ul class="simple"> 385<li><p><a class="reference internal" href="#cryptography.fernet.InvalidToken" title="cryptography.fernet.InvalidToken"><strong>cryptography.fernet.InvalidToken</strong></a> â If a <code class="docutils literal notranslate"><span class="pre">token</span></code> is in any 386way invalid this exception is raised.</p></li> 387<li><p><a class="reference external" href="https://docs.python.org/3/builtins/exceptions.html#TypeError" title="(in Python v3.14)"><strong>TypeError</strong></a> â This exception is raised if the <code class="docutils literal notranslate"><span class="pre">msg</span></code> is not 388<code class="docutils literal notranslate"><span class="pre">bytes</span></code> or <code class="docutils literal notranslate"><span class="pre">str</span></code>.</p></li> 389</ul> 390</dd> 391</dl> 392</dd></dl> 393 394</dd></dl> 395 396<dl class="py class"> 397<dt class="sig sig-object py" id="cryptography.fernet.InvalidToken"> 398<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">cryptography.fernet.</span></span><span class="sig-name descname"><span class="pre">InvalidToken</span></span><a class="reference external" href="https://github.com/pyca/cryptography/blob/main/src/cryptography/fernet.py#L10-L11"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#cryptography.fernet.InvalidToken" title="Link to this definition">ï</a></dt> 399<dd><p>See <a class="reference internal" href="#cryptography.fernet.Fernet.decrypt" title="cryptography.fernet.Fernet.decrypt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Fernet.decrypt()</span></code></a> for more information.</p> 400</dd></dl> 401 402<section id="using-passwords-with-fernet"> 403<h2>Using passwords with Fernet<a class="headerlink" href="#using-passwords-with-fernet" title="Link to this heading">ï</a></h2> 404<p>It is possible to use passwords with Fernet. To do this, you need to run the 405password through a key derivation function. <code class="docutils literal notranslate"><span class="pre">cryptography</span></code> provides several 406such functions; it is generally recommended to use 407<a class="reference internal" href="../hazmat/primitives/key-derivation-functions/#cryptography.hazmat.primitives.kdf.argon2.Argon2id" title="cryptography.hazmat.primitives.kdf.argon2.Argon2id"><code class="xref py py-class docutils literal notranslate"><span class="pre">Argon2id</span></code></a>.</p> 408<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span><span class="w"> </span><span class="nn">base64</span> 409<span class="gp">>>> </span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span> 410<span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.fernet</span><span class="w"> </span><span class="kn">import</span> <span class="n">Fernet</span> 411<span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.hazmat.primitives</span><span class="w"> </span><span class="kn">
411import</span> <span class="n">hashes</span> 412<span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">cryptography.hazmat.primitives.kdf.argon2</span><span class="w"> </span><span class="kn">import</span> <span class="n">Argon2id</span> 413<span class="gp">>>> </span><span class="n">password</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"password"</span> 414<span class="gp">>>> </span><span class="n">salt</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> 415<span class="gp">>>> </span><span class="n">kdf</span> <span class="o">=</span> <span class="n">Argon2id</span><span class="p">(</span> 416<span class="gp">... </span> <span class="n">salt</span><span class="o">=</span><span class="n">salt</span><span class="p">,</span> 417<span class="gp">... </span> <span class="n">length</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> 418<span class="gp">... </span> <span class="n">iterations</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> 419<span class="gp">... </span> <span class="n">lanes</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> 420<span class="gp">... </span> <span class="n">memory_cost</span><span class="o">=</span><span class="mi">2</span><span class="o">**</span><span class="mi">21</span> 421<span class="gp">... </span><span class="p">)</span> 422<span class="gp">>>> </span><span class="n">key</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">urlsafe_b64encode</span><span class="p">(</span><span class="n">kdf</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="n">password</span><span class="p">))</span> 423<span class="gp">>>> </span><span class="n">f</span> <span class="o">=</span> <span class="n">Fernet</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> 424<span class="gp">>>> </span><span class="n">token</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="sa">b</span><span class="s2">"Secret message!"</span><span class="p">)</span> 425<span class="gp">>>> </span><span class="n">token</span> 426<span class="go">b'...'</span> 427<span class="gp">>>> </span><span class="n">f</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">token</span><span class="p">)</span> 428<span class="go">b'Secret message!'</span> 429</pre></div> 430</div> 431<p>In this scheme, the salt has to be stored in a retrievable location in order 432to derive the same key from the password in the future.</p> 433<p>The <a class="reference internal" href="../hazmat/primitives/key-derivation-functions/#cryptography.hazmat.primitives.kdf.argon2.Argon2id" title="cryptography.hazmat.primitives.kdf.argon2.Argon2id"><code class="xref py py-class docutils literal notranslate"><span class="pre">Argon2id</span></code></a> parameters 434in the above code example are based on the recommendations of <a class="reference external" href="https://datatracker.ietf.org/doc/html/rfc9106#name-parameter-choice">IRTF RFC 9106</a> 435for general applications. For memory-constrained applications, the RFC 436recommends <code class="docutils literal notranslate"><span class="pre">iterations=3</span></code> and <code class="docutils literal notranslate"><span class="pre">memory_cost=2**16</span></code>. See that document for 437more information.</p> 438</section> 439<section id="implementation"> 440<h2>Implementation<a class="headerlink" href="#implementation" title="Link to this heading">ï</a></h2> 441<p>Fernet is built on top of a number of standard cryptographic primitives. 442Specifically it uses:</p> 443<ul class="simple"> 444<li><p><a class="reference internal" href="../hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.algorithms.AES" title="cryptography.hazmat.primitives.ciphers.algorithms.AES"><code class="xref py py-class docutils literal notranslate"><span class="pre">AES</span></code></a> in 445<a class="reference internal" href="../hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.modes.CBC" title="cryptography.hazmat.primitives.ciphers.modes.CBC"><code class="xref py py-class docutils literal notranslate"><span class="pre">CBC</span></code></a> mode with a 446128-bit key for encryption; using 447<a class="reference internal" href="../hazmat/primitives/padding/#cryptography.hazmat.primitives.padding.PKCS7" title="cryptography.hazmat.primitives.padding.PKCS7"><code class="xref py py-class docutils literal notranslate"><span class="pre">PKCS7</span></code></a> padding.</p></li> 448<li><p><a class="reference internal" href="../hazmat/primitives/mac/hmac/#cryptography.hazmat.primitives.hmac.HMAC" title="cryptography.hazmat.primitives.hmac.HMAC"><code class="xref py py-class docutils literal notranslate"><span class="pre">HMAC</span></code></a> using 449<a class="reference internal" href="../hazmat/primitives/cryptographic-hashes/#cryptography.hazmat.primitives.hashes.SHA256" title="cryptography.hazmat.primitives.hashes.SHA256"><code class="xref py py-class docutils literal notranslate"><span class="pre">SHA256</span></code></a> for authentication.</p></li> 450<li><p>Initialization vectors are generated using a CSPRNG.</p></li> 451</ul> 452<p>For complete details consult the <a class="reference external" href="https://github.com/fernet/spec/blob/master/Spec.md">specification</a>.</p> 453</section> 454<section id="limitations"> 455<h2>Limitations<a class="headerlink" href="#limitations" title="Link to this heading">ï</a></h2> 456<p>Fernet is ideal for encrypting data that easily fits in memory. As a design 457feature it does not expose unauthenticated bytes. This means that the complete 458message contents must be available in memory, making Fernet generally 459unsuitable for very large files at this time.</p> 460</section> 461</section> 462 463 464 </div> 465 </div> 466 <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> 467 <a href="../" class="btn btn-neutral float-left" title="Welcome to pyca/cryptography" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> 468 <a href="../cobblestone/" class="btn btn-neutral float-right" title="Cobblestone (streaming symmetric encryption)" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> 469 </div> 470 471 <hr/> 472 473 <div role="contentinfo"> 474 <p>© Copyright 2013-2026, Individual Contributors.</p> 475 </div> 476 477 Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a 478 <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> 479 provided by <a href="https://readthedocs.org">Read the Docs</a>. 480 481 482</footer> 483 </div> 484 </div> 485 </section> 486 </div> 487
487<script> 488 jQuery(function () { 489 SphinxRtdTheme.Navigation.enable(true); 490 }); 491 </script>
491 492 493</body> 494</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.