{"title":"暗号署名","version":"6.0","locale":"ja","docname":"topics/signing","url":"/ja/6.0/topics/signing/","canonical":"https://djangodocs.dev/ja/6.0/topics/signing/","summary":"ウェブアプリケーションのセキュリティの黄金律は、信頼できない情報源からのデータを決して信頼しないことです。時には、信頼されていない媒体を通してデータを渡すことが有用な場合もあります。暗号的に署名された値は、改ざんが検知されることを前提に、信頼されていない経路を安全に通過させることができます。 Django…","html":"<span id=\"cryptographic-signing\"></span><h1>暗号署名<a class=\"heading-anchor\" href=\"#module-django.core.signing\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>ウェブアプリケーションのセキュリティの黄金律は、信頼できない情報源からのデータを決して信頼しないことです。時には、信頼されていない媒体を通してデータを渡すことが有用な場合もあります。暗号的に署名された値は、改ざんが検知されることを前提に、信頼されていない経路を安全に通過させることができます。</p>\n<p>Django は、値の署名に関する低レベル API と、Web アプリケーションでの署名の最も一般的な用途の一つである署名付きクッキーの設定と読み取りに関する高レベル API の両方を提供しています。</p>\n<p>また、以下のような場合にも署名が役に立つでしょう:</p>\n<ul class=\"simple\">\n<li><p>パスワードを紛失したユーザーに送信する「アカウントの回復」URLの生成。</p></li>\n<li><p>非表示のフォームフィールドに保存されたデータが改ざんされていないことの確認。</p></li>\n<li><p>保護されたリソースへの一時的なアクセスを許可するためのワンタイムシークレットURLの生成。例えばユーザーが料金を支払ったダウンロード可能なファイルなど。</p></li>\n</ul>\n<section id=\"protecting-secret-key-and-secret-key-fallbacks\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">SECRET_KEY_FALLBACKS</span></code> の保護<a class=\"heading-anchor\" href=\"#protecting-secret-key-and-secret-key-fallbacks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/ja/6.0/ref/django-admin/#django-admin-startproject\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">startproject</span></code></a> によって新しいプロジェクトを作る際、 <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code> が生成され、ランダムな <a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code></a> を得ます。この値が、署名されたデータを安全に保つ鍵になります。このキーを安全に保存するとこは極めて重要で、さもなければ攻撃を行うひとたちが彼らの署名を生成するのにも使えるからです。</p>\n<p><a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY_FALLBACKS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY_FALLBACKS</span></code></a> は秘密鍵のローテーションに使用できます。この値はデータへの署名には使用されませんが、指定された場合は署名されたデータを検証するために使用されるので、安全に保つ必要があります。</p>\n</section>\n<section id=\"using-the-low-level-api\">\n<h2>低レベルの API を利用する<a class=\"heading-anchor\" href=\"#using-the-low-level-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django の署名メソッドは <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.signing</span></code> モジュールにあります。値に署名するには、まず <code class=\"docutils literal notranslate\"><span class=\"pre\">Signer</span></code> インスタンスを作成します。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signing</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Signer</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">Signer</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"s2\">&quot;My string&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span>\n<span class=\"go\">&#39;My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0&#39;</span>\n</code></pre></div>\n<p>署名が文字列の最後にコロンに続いて付加されます。元の値を取得するには、<code class=\"docutils literal notranslate\"><span class=\"pre\">unsign</span></code> メソッドを使用します。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">original</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">original</span>\n<span class=\"go\">&#39;My string&#39;</span>\n</code></pre></div>\n<p>もし <code class=\"docutils literal notranslate\"><span class=\"pre\">sign</span></code> に文字列でない値を渡すと、その値は署名される前に強制的に文字列に変換され、<code class=\"docutils literal notranslate\"><span class=\"pre\">unsign</span></code> の結果にはその文字列の値が返されます。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signed</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"mf\">2.5</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">original</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">signed</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">original</span>\n<span class=\"go\">&#39;2.5&#39;</span>\n</code></pre></div>\n<p>リスト、タプル、辞書を保護したい場合は 、<code class=\"docutils literal notranslate\"><span class=\"pre\">sign_object()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">unsign_object()</span></code> メソッドを使います。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signed_obj</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign_object</span><span class=\"p\">({</span><span class=\"s2\">&quot;message&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Hello!&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signed_obj</span>\n<span class=\"go\">&#39;eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign_object</span><span class=\"p\">(</span><span class=\"n\">signed_obj</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">obj</span>\n<span class=\"go\">{&#39;message&#39;: &#39;Hello!&#39;}</span>\n</code></pre></div>\n<p>詳細は <a class=\"reference internal\" href=\"#signing-complex-data\"><span class=\"std std-ref\">複雑なデータ構造の保護</span></a> を参照してください。</p>\n<p>何らかの理由により署名の値が書き換わってしまった場合、<code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.signing.BadSignature</span></code> 例外が起こります。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">signing</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">+=</span> <span class=\"s2\">&quot;m&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">try</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"n\">original</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"k\">except</span> <span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">BadSignature</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Tampering detected!&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n</code></pre></div>\n<p>デフォルトでは、<code class=\"docutils literal notranslate\"><span class=\"pre\">Signer</span></code> クラスは <a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code></a> 設定の値を署名生成に利用します。次のように <code class=\"docutils literal notranslate\"><span class=\"pre\">Signer</span></code> のコンストラクタに任意の値を渡すことで、異なる秘密鍵を使用することもできます。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">Signer</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"o\">=</span><span class=\"s2\">&quot;my-other-secret&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"s2\">&quot;My string&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span>\n<span class=\"go\">&#39;My string:o3DrrsT6JRB73t-HDymfDNbTSxfMlom2d8TiUlb1hWY&#39;</span>\n</code></pre></div>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.Signer\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Signer</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"keyword-only-separator o\"><abbr title=\"Keyword-only parameters separator (PEP 3102)\"><span class=\"pre\">*</span></abbr></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">key</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sep</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">':'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">salt</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">algorithm</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fallback_keys</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=\"heading-anchor\" href=\"#django.core.signing.Signer\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Returns a signer which uses <code class=\"docutils literal notranslate\"><span class=\"pre\">key</span></code> to generate signatures and <code class=\"docutils literal notranslate\"><span class=\"pre\">sep</span></code> to\nseparate values. <code class=\"docutils literal notranslate\"><span class=\"pre\">sep</span></code> cannot be in the <span class=\"target\" id=\"index-0\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc4648.html#section-5\"><strong>URL safe base64 alphabet</strong></a>. This alphabet contains alphanumeric characters, hyphens,\nand underscores. <code class=\"docutils literal notranslate\"><span class=\"pre\">algorithm</span></code> must be an algorithm supported by\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/hashlib.html#module-hashlib\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">hashlib</span></code></a>, it defaults to <code class=\"docutils literal notranslate\"><span class=\"pre\">'sha256'</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">fallback_keys</span></code> is a list\nof additional values used to validate signed data, defaults to\n<a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY_FALLBACKS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY_FALLBACKS</span></code></a>.</p>\n</dd></dl>\n\n<section id=\"using-the-salt-argument\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">salt</span></code> 引数を使用する<a class=\"heading-anchor\" href=\"#using-the-salt-argument\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>特定の文字列が出現するたびに同じ署名ハッシュを使用したくない場合は、オプションで <code class=\"docutils literal notranslate\"><span class=\"pre\">Signer</span></code> クラスの引数 <code class=\"docutils literal notranslate\"><span class=\"pre\">salt</span></code> を使用できます。ソルトを使用すると、署名ハッシュ関数にソルトと <a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code></a> の両方をシードにします:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">Signer</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"s2\">&quot;My string&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign_object</span><span class=\"p\">({</span><span class=\"s2\">&quot;message&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Hello!&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&#39;eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">Signer</span><span class=\"p\">(</span><span class=\"n\">salt</span><span class=\"o\">=</span><span class=\"s2\">&quot;extra&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"s2\">&quot;My string&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"s2\">&quot;My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;My string&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign_object</span><span class=\"p\">({</span><span class=\"s2\">&quot;message&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Hello!&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">&#39;eyJtZXNzYWdlIjoiSGVsbG8hIn0:-UWSLCE-oUAHzhkHviYz3SOZYBjFKllEOyVZNuUtM-I&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign_object</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;eyJtZXNzYWdlIjoiSGVsbG8hIn0:-UWSLCE-oUAHzhkHviYz3SOZYBjFKllEOyVZNuUtM-I&quot;</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">{&#39;message&#39;: &#39;Hello!&#39;}</span>\n</code></pre></div>\n<p>Using salt in this way puts the different signatures into different\nnamespaces. A signature that comes from one namespace (a particular salt\nvalue) cannot be used to validate the same plaintext string in a different\nnamespace that is using a different salt setting. The result is to prevent an\nattacker from using a signed string generated in one place in the code as input\nto another piece of code that is generating (and verifying) signatures using a\ndifferent salt.</p>\n<p><a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code></a> とは異なり、salt 引数は秘密にする必要はありません。</p>\n</section>\n<section id=\"verifying-timestamped-values\">\n<h3>タイムスタンプ値の検証<a class=\"heading-anchor\" href=\"#verifying-timestamped-values\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">TimestampSigner</span></code> は <a class=\"reference internal\" href=\"#django.core.signing.Signer\" title=\"django.core.signing.Signer\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Signer</span></code></a> のサブクラスで、値に署名されたタイムスタンプを追加します。これにより、署名された値が指定された期間内に作成されたことを確認できます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">datetime</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timedelta</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signing</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TimestampSigner</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">TimestampSigner</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign</span><span class=\"p\">(</span><span class=\"s2\">&quot;hello&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span>\n<span class=\"go\">&#39;hello:1stLqR:_rvr4oXCgT4HyfwjXaU39QvTnuNuUthFRCzNOy4Hqt0&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;hello&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">max_age</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n<span class=\"go\">SignatureExpired: Signature age 15.5289158821 &gt; 10 seconds</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">max_age</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n<span class=\"go\">&#39;hello&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">max_age</span><span class=\"o\">=</span><span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">seconds</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">))</span>\n<span class=\"go\">&#39;hello&#39;</span>\n</code></pre></div>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.TimestampSigner\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">TimestampSigner</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"keyword-only-separator o\"><abbr title=\"Keyword-only parameters separator (PEP 3102)\"><span class=\"pre\">*</span></abbr></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">key</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sep</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">':'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">salt</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">algorithm</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'sha256'</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.signing.TimestampSigner\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.TimestampSigner.sign\">\n<span class=\"sig-name descname\"><span class=\"pre\">sign</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">value</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.signing.TimestampSigner.sign\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>値 <code class=\"docutils literal notranslate\"><span class=\"pre\">value</span></code> に署名し、現在のタイムスタンプを追加します。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.TimestampSigner.unsign\">\n<span class=\"sig-name descname\"><span class=\"pre\">unsign</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">value</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_age</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=\"heading-anchor\" href=\"#django.core.signing.TimestampSigner.unsign\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Checks if <code class=\"docutils literal notranslate\"><span class=\"pre\">value</span></code> was signed less than <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> seconds ago,\notherwise raises <code class=\"docutils literal notranslate\"><span class=\"pre\">SignatureExpired</span></code>. The <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> parameter can\naccept an integer or a <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.timedelta\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">datetime.timedelta</span></code></a> object.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.TimestampSigner.sign_object\">\n<span class=\"sig-name descname\"><span class=\"pre\">sign_object</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">serializer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">JSONSerializer</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">compress</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.signing.TimestampSigner.sign_object\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>複雑なデータ構造（例えば、リスト、タプル、または辞書）をエンコードし、オプションで圧縮し、現在のタイムスタンプを追加し署名します。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.TimestampSigner.unsign_object\">\n<span class=\"sig-name descname\"><span class=\"pre\">unsign_object</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">signed_obj</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">serializer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">JSONSerializer</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_age</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=\"heading-anchor\" href=\"#django.core.signing.TimestampSigner.unsign_object\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Checks if <code class=\"docutils literal notranslate\"><span class=\"pre\">signed_obj</span></code> was signed less than <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> seconds ago,\notherwise raises <code class=\"docutils literal notranslate\"><span class=\"pre\">SignatureExpired</span></code>. The <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> parameter can\naccept an integer or a <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.timedelta\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">datetime.timedelta</span></code></a> object.</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"protecting-complex-data-structures\">\n<span id=\"signing-complex-data\"></span><h3>複雑なデータ構造の保護<a class=\"heading-anchor\" href=\"#protecting-complex-data-structures\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>リスト、タプル、辞書を保護したい場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Signer.sign_object()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">unsign_object()</span></code> メソッド、あるいは署名モジュールの <code class=\"docutils literal notranslate\"><span class=\"pre\">dumps()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">loads()</span></code> 関数 (<code class=\"docutils literal notranslate\"><span class=\"pre\">TimestampSigner(salt='django.core.signing').sign_object()/unsign_object()</span></code> のショートカットです) を使って保護できます。これらは JSON シリアライズを使っています。JSONにすることで、 <a class=\"reference internal\" href=\"/ja/6.0/ref/settings/#std-setting-SECRET_KEY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY</span></code></a> が盗まれても、攻撃者が pickle フォーマットを悪用して任意のコマンドを実行できないようにします:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">signing</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span> <span class=\"o\">=</span> <span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">TimestampSigner</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">sign_object</span><span class=\"p\">({</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span>\n<span class=\"go\">&#39;eyJmb28iOiJiYXIifQ:1stLrZ:_QiOBHafwucBF9FyAr54qEs84ZO1UdsO1XiTJCvvdno&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signer</span><span class=\"o\">.</span><span class=\"n\">unsign_object</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;bar&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">dumps</span><span class=\"p\">({</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span>\n<span class=\"go\">&#39;eyJmb28iOiJiYXIifQ:1stLsC:JItq2ZVjmAK6ivrWI-v1Gk1QVf2hOF52oaEqhZHca7I&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">loads</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;bar&#39;}</span>\n</code></pre></div>\n<p>JSONの性質上（ネイティブではリストとタプルの区別がありません）、タプルを渡すと <code class=\"docutils literal notranslate\"><span class=\"pre\">signing.loads(object)</span></code> からリストが返されます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">signing</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">dumps</span><span class=\"p\">((</span><span class=\"s2\">&quot;a&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;b&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;c&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">signing</span><span class=\"o\">.</span><span class=\"n\">loads</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n<span class=\"go\">[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]</span>\n</code></pre></div>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.dumps\">\n<span class=\"sig-name descname\"><span class=\"pre\">dumps</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">key</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">salt</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'django.core.signing'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">serializer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">JSONSerializer</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">compress</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.signing.dumps\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>URL セーフな、署名付き base64 圧縮 JSON 文字列を返します。シリアライズされたオブジェクトは <a class=\"reference internal\" href=\"#django.core.signing.TimestampSigner\" title=\"django.core.signing.TimestampSigner\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TimestampSigner</span></code></a> を使って署名されます。</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.core.signing.loads\">\n<span class=\"sig-name descname\"><span class=\"pre\">loads</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">string</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">key</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">salt</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'django.core.signing'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">serializer</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">JSONSerializer</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_age</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fallback_keys</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=\"heading-anchor\" href=\"#django.core.signing.loads\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><code class=\"docutils literal notranslate\"><span class=\"pre\">dumps()</span></code> の逆で、署名に失敗した場合に <code class=\"docutils literal notranslate\"><span class=\"pre\">BadSignature</span></code> を返します。指定された場合は <code class=\"docutils literal notranslate\"><span class=\"pre\">max_age</span></code> (秒単位) をチェックします。</p>\n</dd></dl>\n\n</section>\n</section>","rootId":"module-django.core.signing","toc":[{"title":"SECRET_KEY と SECRET_KEY_FALLBACKS の保護","anchor":"protecting-secret-key-and-secret-key-fallbacks","children":[]},{"title":"低レベルの API を利用する","anchor":"using-the-low-level-api","children":[{"title":"salt 引数を使用する","anchor":"using-the-salt-argument","children":[]},{"title":"タイムスタンプ値の検証","anchor":"verifying-timestamped-values","children":[]},{"title":"複雑なデータ構造の保護","anchor":"protecting-complex-data-structures","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/6.0/topics/"}],"prev":{"docname":"topics/composite-primary-key","title":"複合主キー","url":"/ja/6.0/topics/composite-primary-key/"},"next":{"docname":"topics/email","title":"メールを送信する","url":"/ja/6.0/topics/email/"},"formats":{"html":"/ja/6.0/topics/signing/","markdown":"/ja/6.0/topics/signing.md","json":"/ja/6.0/topics/signing.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/topics/signing.txt","official":"https://docs.djangoproject.com/ja/6.0/topics/signing/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}