{"title":"Djangoにおけるパスワード管理","version":"4.0","locale":"ja","docname":"topics/auth/passwords","url":"/ja/4.0/topics/auth/passwords/","canonical":"https://djangodocs.dev/ja/4.0/topics/auth/passwords/","summary":"パスワード管理は一般的に、不必要に再発明されるべきではないものです。Djangoはユーザーのパスワードを管理するための安全で柔軟なツールセットを提供するよう努めて…","html":"<h1>Djangoにおけるパスワード管理<a class=\"heading-anchor\" href=\"#password-management-in-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>パスワード管理は一般的に、不必要に再発明されるべきではないものです。Djangoはユーザーのパスワードを管理するための安全で柔軟なツールセットを提供するよう努めています。このドキュメントでは、Djangoがパスワードを保存する方法、ストレージハッシュの設定方法、およびハッシュされたパスワードを扱ういくつかのユーティリティについて説明します。</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">参考</p>\n<p>ユーザーが強力なパスワードを使ったとしても、攻撃者が通信経路上において盗聴をおこなう可能性があります。パスワード（または他の機密データ）がプレーンなHTTP接続で送信されないように、 <a class=\"reference internal\" href=\"/ja/4.0/topics/security/#security-recommendation-ssl\"><span class=\"std std-ref\">HTTPS</span></a> を使用してください。なぜなら、HTTPはパスワードスニッフィングに対して脆弱であるからです。</p>\n</aside>\n<section id=\"how-django-stores-passwords\">\n<span id=\"auth-password-storage\"></span><h2>Djangoのパスワード保存方法<a class=\"heading-anchor\" href=\"#how-django-stores-passwords\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>DjangoはデフォルトでPBKDF2を利用した、柔軟なパスワード保存システムを提供します。</p>\n<p>The <a class=\"reference internal\" href=\"/ja/4.0/ref/contrib/auth/#django.contrib.auth.models.User.password\" title=\"django.contrib.auth.models.User.password\"><code class=\"xref py py-attr docutils literal notranslate\">password</code></a> attribute of a\n<a class=\"reference internal\" href=\"/ja/4.0/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\">User</code></a> object is a string in this format:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>&lt;algorithm&gt;$&lt;iterations&gt;$&lt;salt&gt;$&lt;hash&gt;\n</code></pre></div>\n<p>これらはユーザーのパスワードを保存するためのコンポーネントで、ハッシュアルゴリズム、アルゴリズムのイテレーション回数（ワークファクター）、ランダムなソルト、そして結果のパスワードハッシュをドル記号($)で区切ったものです。このアルゴリズムは、Djangoが使用できる数多くの一方向ハッシュ、またはパスワード保存アルゴリズム（下記参照）の一つです。イテレーションはハッシュに対してアルゴリズムが実行された回数を表します。ソルトは使用されたランダムシードで、ハッシュは一方向ハッシュ関数の実行結果です。</p>\n<p>デフォルトでは、Djangoは <a class=\"reference external\" href=\"https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf\">NIST</a> が推奨するパスワードストレッチングメカニズムである <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/PBKDF2\">PBKDF2</a> アルゴリズムと SHA256 ハッシュを使用します。これはほとんどのユーザーに十分有効なはずです。非常に安全で、クラックするのに膨大な計算時間を必要とします。</p>\n<p>ただし、要件に応じて、異なるアルゴリズムを使用することも、一部のセキュリティ状況に合わせてカスタムアルゴリズムを使用することもできます。繰り返しますが、ほとんどのユーザーはこれを行う必要はありません。よくわからない場合、おそらくそうしないほうが良いです。もしそうする場合は、こちらをお読みください:</p>\n<p>Djangoは <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> 設定に基づき、使用するアルゴリズムを選択します。これは、Djangoインストールがサポートするハッシュアルゴリズムクラスのリストです。このリストの最初のエントリ（つまり、 <code class=\"docutils literal notranslate\">settings.PASSWORD_HASHERS[0]</code> ）がパスワードの保存に使用され、他の全てのエントリは、既に存在するパスワードの検証に使用できる有効性検証ハッシャです。つまり、他のアルゴリズムを使用したい場合は <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> を修正して、使用したいアルゴリズムをリストの最初にする必要があります。</p>\n<p>デフォルトでの <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a></p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>これは、Djangoは <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/PBKDF2\">PBKDF2</a> を使用して全てのパスワードを保存しますが、PBKDF2SHA1、 <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Argon2\">argon2</a> 、および <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Bcrypt\">bcrypt</a> で保存されたパスワードのチェックもサポートすることを意味しています。</p>\n<p>次のいくつかのセクションでは、高度なユーザーがこの設定を変更するための一般的な方法について説明します。</p>\n<section id=\"using-argon2-with-django\">\n<span id=\"argon2-usage\"></span><h3>Using Argon2 with Django<a class=\"heading-anchor\" href=\"#using-argon2-with-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Argon2\">Argon2</a> is the winner of the 2015 <a class=\"reference external\" href=\"https://www.password-hashing.net/\">Password Hashing Competition</a>, a community\norganized open competition to select a next generation hashing algorithm. It's\ndesigned not to be easier to compute on custom hardware than it is to compute\non an ordinary CPU.</p>\n<p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Argon2\">Argon2</a> is not the default for Django because it requires a third-party\nlibrary. The Password Hashing Competition panel, however, recommends immediate\nuse of Argon2 rather than the other algorithms supported by Django.</p>\n<p>To use Argon2 as your default storage algorithm, do the following:</p>\n<ol class=\"arabic\">\n<li><p>Install the <a class=\"reference external\" href=\"https://pypi.org/project/argon2-cffi/\">argon2-cffi library</a>.  This can be done by running\n<code class=\"docutils literal notranslate\">python -m pip install django[argon2]</code>, which is equivalent to\n<code class=\"docutils literal notranslate\">python -m pip install argon2-cffi</code> (along with any version requirement\nfrom Django's <code class=\"docutils literal notranslate\">setup.cfg</code>).</p></li>\n<li><p>Modify <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> to list <code class=\"docutils literal notranslate\">Argon2PasswordHasher</code> first.\nThat is, in your settings file, you'd put:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Keep and/or add any entries in this list if you need Django to <a class=\"reference internal\" href=\"#password-upgrades\"><span class=\"std std-ref\">upgrade\npasswords</span></a>.</p>\n</li>\n</ol>\n</section>\n<section id=\"using-bcrypt-with-django\">\n<span id=\"bcrypt-usage\"></span><h3>Using <code class=\"docutils literal notranslate\">bcrypt</code> with Django<a class=\"heading-anchor\" href=\"#using-bcrypt-with-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Bcrypt\">Bcrypt</a> is a popular password storage algorithm that's specifically designed\nfor long-term password storage. It's not the default used by Django since it\nrequires the use of third-party libraries, but since many people may want to\nuse it Django supports bcrypt with minimal effort.</p>\n<p>To use Bcrypt as your default storage algorithm, do the following:</p>\n<ol class=\"arabic\">\n<li><p>Install the <a class=\"reference external\" href=\"https://pypi.org/project/bcrypt/\">bcrypt library</a>. This can be done by running\n<code class=\"docutils literal notranslate\">python -m pip install django[bcrypt]</code>, which is equivalent to\n<code class=\"docutils literal notranslate\">python -m pip install bcrypt</code> (along with any version requirement from\nDjango's <code class=\"docutils literal notranslate\">setup.cfg</code>).</p></li>\n<li><p>Modify <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> to list <code class=\"docutils literal notranslate\">BCryptSHA256PasswordHasher</code>\nfirst. That is, in your settings file, you'd put:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Keep and/or add any entries in this list if you need Django to <a class=\"reference internal\" href=\"#password-upgrades\"><span class=\"std std-ref\">upgrade\npasswords</span></a>.</p>\n</li>\n</ol>\n<p>That's it -- now your Django install will use Bcrypt as the default storage\nalgorithm.</p>\n</section>\n<section id=\"using-scrypt-with-django\">\n<span id=\"scrypt-usage\"></span><h3>Using <code class=\"docutils literal notranslate\">scrypt</code> with Django<a class=\"heading-anchor\" href=\"#using-scrypt-with-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"4.0\" role=\"note\">\n<p class=\"version-note-title\">New in Django 4.0</p></aside>\n<p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Scrypt\">scrypt</a> is similar to PBKDF2 and bcrypt in utilizing a set number of iterations\nto slow down brute-force attacks. However, because PBKDF2 and bcrypt do not\nrequire a lot of memory, attackers with sufficient resources can launch\nlarge-scale parallel attacks in order to speed up the attacking process.\n<a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Scrypt\">scrypt</a> is specifically designed to use more memory compared to other\npassword-based key derivation functions in order to limit the amount of\nparallelism an attacker can use, see <span class=\"target\" id=\"index-0\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7914.html\"><strong>RFC 7914</strong></a> for more details.</p>\n<p>To use <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Scrypt\">scrypt</a> as your default storage algorithm, do the following:</p>\n<ol class=\"arabic\">\n<li><p>Modify <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> to list <code class=\"docutils literal notranslate\">ScryptPasswordHasher</code> first.\nThat is, in your settings file:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Keep and/or add any entries in this list if you need Django to <a class=\"reference internal\" href=\"#password-upgrades\"><span class=\"std std-ref\">upgrade\npasswords</span></a>.</p>\n</li>\n</ol>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p><code class=\"docutils literal notranslate\">scrypt</code> requires OpenSSL 1.1+.</p>\n</aside>\n</section>\n<section id=\"increasing-the-salt-entropy\">\n<h3>Increasing the salt entropy<a class=\"heading-anchor\" href=\"#increasing-the-salt-entropy\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"3.2\" role=\"note\">\n<p class=\"version-note-title\">New in Django 3.2</p></aside>\n<p>Most password hashes include a salt along with their password hash in order to\nprotect against rainbow table attacks. The salt itself is a random value which\nincreases the size and thus the cost of the rainbow table and is currently set\nat 128 bits with the <code class=\"docutils literal notranslate\">salt_entropy</code> value in the <code class=\"docutils literal notranslate\">BasePasswordHasher</code>. As\ncomputing and storage costs decrease this value should be raised. When\nimplementing your own password hasher you are free to override this value in\norder to use a desired entropy level for your password hashes. <code class=\"docutils literal notranslate\">salt_entropy</code>\nis measured in bits.</p>\n<aside class=\"admonition-implementation-detail admonition\" role=\"note\">\n<p class=\"admonition-title\">Implementation detail</p>\n<p>Due to the method in which salt values are stored the <code class=\"docutils literal notranslate\">salt_entropy</code>\nvalue is effectively a minimum value. For instance a value of 128 would\nprovide a salt which would actually contain 131 bits of entropy.</p>\n</aside>\n</section>\n<section id=\"increasing-the-work-factor\">\n<span id=\"increasing-password-algorithm-work-factor\"></span><h3>Increasing the work factor<a class=\"heading-anchor\" href=\"#increasing-the-work-factor\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"pbkdf2-and-bcrypt\">\n<h4>PBKDF2 and bcrypt<a class=\"heading-anchor\" href=\"#pbkdf2-and-bcrypt\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>The PBKDF2 and bcrypt algorithms use a number of iterations or rounds of\nhashing. This deliberately slows down attackers, making attacks against hashed\npasswords harder. However, as computing power increases, the number of\niterations needs to be increased. We've chosen a reasonable default (and will\nincrease it with each release of Django), but you may wish to tune it up or\ndown, depending on your security needs and available processing power. To do so,\nyou'll subclass the appropriate algorithm and override the <code class=\"docutils literal notranslate\">iterations</code>\nparameter (use the <code class=\"docutils literal notranslate\">rounds</code> parameter when subclassing a bcrypt hasher). For\nexample, to increase the number of iterations used by the default PBKDF2\nalgorithm:</p>\n<ol class=\"arabic\">\n<li><p>Create a subclass of <code class=\"docutils literal notranslate\">django.contrib.auth.hashers.PBKDF2PasswordHasher</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.hashers</span> <span class=\"kn\">import</span> PBKDF2PasswordHasher\n\n<span class=\"k\">class</span> <span class=\"nc\">MyPBKDF2PasswordHasher</span><span class=\"p\">(</span>PBKDF2PasswordHasher<span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    iterations <span class=\"o\">=</span> PBKDF2PasswordHasher<span class=\"o\">.</span>iterations <span class=\"o\">*</span> <span class=\"mi\">100</span>\n</code></pre></div>\n<p>Save this somewhere in your project. For example, you might put this in\na file like <code class=\"docutils literal notranslate\">myproject/hashers.py</code>.</p>\n</li>\n<li><p>Add your new hasher as the first entry in <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;myproject.hashers.MyPBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n</li>\n</ol>\n<p>That's it -- now your Django install will use more iterations when it\nstores passwords using PBKDF2.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>bcrypt <code class=\"docutils literal notranslate\">rounds</code> is a logarithmic work factor, e.g. 12 rounds means\n<code class=\"docutils literal notranslate\">2 ** 12</code> iterations.</p>\n</aside>\n</section>\n<section id=\"argon2\">\n<h4>Argon2<a class=\"heading-anchor\" href=\"#argon2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Argon2 has three attributes that can be customized:</p>\n<ol class=\"arabic simple\">\n<li><p><code class=\"docutils literal notranslate\">time_cost</code> controls the number of iterations within the hash.</p></li>\n<li><p><code class=\"docutils literal notranslate\">memory_cost</code> controls the size of memory that must be used during the\ncomputation of the hash.</p></li>\n<li><p><code class=\"docutils literal notranslate\">parallelism</code> controls how many CPUs the computation of the hash can be\nparallelized on.</p></li>\n</ol>\n<p>The default values of these attributes are probably fine for you. If you\ndetermine that the password hash is too fast or too slow, you can tweak it as\nfollows:</p>\n<ol class=\"arabic simple\">\n<li><p>Choose <code class=\"docutils literal notranslate\">parallelism</code> to be the number of threads you can\nspare computing the hash.</p></li>\n<li><p>Choose <code class=\"docutils literal notranslate\">memory_cost</code> to be the KiB of memory you can spare.</p></li>\n<li><p>Adjust <code class=\"docutils literal notranslate\">time_cost</code> and measure the time hashing a password takes.\nPick a <code class=\"docutils literal notranslate\">time_cost</code> that takes an acceptable time for you.\nIf <code class=\"docutils literal notranslate\">time_cost</code> set to 1 is unacceptably slow, lower <code class=\"docutils literal notranslate\">memory_cost</code>.</p></li>\n</ol>\n<aside class=\"admonition-memory-cost-interpretation admonition\" role=\"note\">\n<p class=\"admonition-title\"><code class=\"docutils literal notranslate\">memory_cost</code> interpretation</p>\n<p>The argon2 command-line utility and some other libraries interpret the\n<code class=\"docutils literal notranslate\">memory_cost</code> parameter differently from the value that Django uses. The\nconversion is given by <code class=\"docutils literal notranslate\">memory_cost == 2 ** memory_cost_commandline</code>.</p>\n</aside>\n</section>\n<section id=\"scrypt\">\n<h4><code class=\"docutils literal notranslate\">scrypt</code><a class=\"heading-anchor\" href=\"#scrypt\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<aside class=\"version-note version-added\" data-version=\"4.0\" role=\"note\">\n<p class=\"version-note-title\">New in Django 4.0</p></aside>\n<p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Scrypt\">scrypt</a> has four attributes that can be customized:</p>\n<ol class=\"arabic simple\">\n<li><p><code class=\"docutils literal notranslate\">work_factor</code> controls the number of iterations within the hash.</p></li>\n<li><p><code class=\"docutils literal notranslate\">block_size</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">parallelism</code> controls how many threads will run in parallel.</p></li>\n<li><p><code class=\"docutils literal notranslate\">maxmem</code> limits the maximum size of memory that can be used during the\ncomputation of the hash. Defaults to <code class=\"docutils literal notranslate\">0</code>, which means the default\nlimitation from the OpenSSL library.</p></li>\n</ol>\n<p>We've chosen reasonable defaults, but you may wish to tune it up or down,\ndepending on your security needs and available processing power.</p>\n<aside class=\"admonition-estimating-memory-usage admonition\" role=\"note\">\n<p class=\"admonition-title\">Estimating memory usage</p>\n<p>The minimum memory requirement of <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Scrypt\">scrypt</a> is:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>work_factor <span class=\"o\">*</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> block_size <span class=\"o\">*</span> <span class=\"mi\">64</span>\n</code></pre></div>\n<p>so you may need to tweak <code class=\"docutils literal notranslate\">maxmem</code> when changing the <code class=\"docutils literal notranslate\">work_factor</code> or\n<code class=\"docutils literal notranslate\">block_size</code> values.</p>\n</aside>\n</section>\n</section>\n<section id=\"password-upgrading\">\n<span id=\"password-upgrades\"></span><h3>パスワードの更新<a class=\"heading-anchor\" href=\"#password-upgrading\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>ユーザーがログインする際、もしそのパスワードが推奨されるアルゴリズム以外で保存されていた場合、Djangoは自動で推奨されるアルゴリズムへ更新します。つまり、Djangoの古いインストールでも、ユーザーのログイン時に自動的にセキュリティが強化され、新しい（より良い）保存アルゴリズムが開発されるたびに切り替えることができるということです。</p>\n<p>However, Django can only upgrade passwords that use algorithms mentioned in\n<a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a>, so as you upgrade to new systems you should make\nsure never to <em>remove</em> entries from this list. If you do, users using\nunmentioned algorithms won't be able to upgrade. Hashed passwords will be\nupdated when increasing (or decreasing) the number of PBKDF2 iterations, bcrypt\nrounds, or argon2 attributes.</p>\n<p>データベース上の全てのパスワードがデフォルトのハッシュアルゴリズムでエンコードされていない場合、デフォルト以外のアルゴリズムでエンコードされたパスワードを持つユーザーと、存在しないユーザー（デフォルトのハッシュアルゴリズムが実行されます）に対するログインリクエストにかかる時間の差に起因する、ユーザー列挙型タイミング攻撃に対して脆弱になる可能性があることに注意してください。 <a class=\"reference internal\" href=\"#wrapping-password-hashers\"><span class=\"std std-ref\">古いパスワードハッシュの更新</span></a> によりこれを軽減できます。</p>\n</section>\n<section id=\"password-upgrading-without-requiring-a-login\">\n<span id=\"wrapping-password-hashers\"></span><h3>Password upgrading without requiring a login<a class=\"heading-anchor\" href=\"#password-upgrading-without-requiring-a-login\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you have an existing database with an older, weak hash such as MD5 or SHA1,\nyou might want to upgrade those hashes yourself instead of waiting for the\nupgrade to happen when a user logs in (which may never happen if a user doesn't\nreturn to your site). In this case, you can use a &quot;wrapped&quot; password hasher.</p>\n<p>For this example, we'll migrate a collection of SHA1 hashes to use\nPBKDF2(SHA1(password)) and add the corresponding password hasher for checking\nif a user entered the correct password on login. We assume we're using the\nbuilt-in <code class=\"docutils literal notranslate\">User</code> model and that our project has an <code class=\"docutils literal notranslate\">accounts</code> app. You can\nmodify the pattern to work with any algorithm or with a custom user model.</p>\n<p>First, we'll add the custom hasher:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">accounts/hashers.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.hashers</span> <span class=\"kn\">import</span> <span class=\"p\">(</span>\n    PBKDF2PasswordHasher<span class=\"p\">,</span> SHA1PasswordHasher<span class=\"p\">,</span>\n<span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PBKDF2WrappedSHA1PasswordHasher</span><span class=\"p\">(</span>PBKDF2PasswordHasher<span class=\"p\">):</span>\n    algorithm <span class=\"o\">=</span> <span class=\"s1\">&#39;pbkdf2_wrapped_sha1&#39;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">encode_sha1_hash</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> sha1_hash<span class=\"p\">,</span> salt<span class=\"p\">,</span> iterations<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>encode<span class=\"p\">(</span>sha1_hash<span class=\"p\">,</span> salt<span class=\"p\">,</span> iterations<span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">encode</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> password<span class=\"p\">,</span> salt<span class=\"p\">,</span> iterations<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        _<span class=\"p\">,</span> _<span class=\"p\">,</span> sha1_hash <span class=\"o\">=</span> SHA1PasswordHasher<span class=\"p\">()</span><span class=\"o\">.</span>encode<span class=\"p\">(</span>password<span class=\"p\">,</span> salt<span class=\"p\">)</span><span class=\"o\">.</span>split<span class=\"p\">(</span><span class=\"s1\">&#39;$&#39;</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>encode_sha1_hash<span class=\"p\">(</span>sha1_hash<span class=\"p\">,</span> salt<span class=\"p\">,</span> iterations<span class=\"p\">)</span>\n</code></pre></figure>\n<p>The data migration might look something like:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">accounts/migrations/0002_migrate_sha1_passwords.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n<span class=\"kn\">from</span> <span class=\"nn\">..hashers</span> <span class=\"kn\">import</span> PBKDF2WrappedSHA1PasswordHasher\n\n\n<span class=\"k\">def</span> <span class=\"nf\">forwards_func</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    User <span class=\"o\">=</span> apps<span class=\"o\">.</span>get_model<span class=\"p\">(</span><span class=\"s1\">&#39;auth&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;User&#39;</span><span class=\"p\">)</span>\n    users <span class=\"o\">=</span> User<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>password__startswith<span class=\"o\">=</span><span class=\"s1\">&#39;sha1$&#39;</span><span class=\"p\">)</span>\n    hasher <span class=\"o\">=</span> PBKDF2WrappedSHA1PasswordHasher<span class=\"p\">()</span>\n    <span class=\"k\">for</span> user <span class=\"ow\">in</span> users<span class=\"p\">:</span>\n        algorithm<span class=\"p\">,</span> salt<span class=\"p\">,</span> sha1_hash <span class=\"o\">=</span> user<span class=\"o\">.</span>password<span class=\"o\">.</span>split<span class=\"p\">(</span><span class=\"s1\">&#39;$&#39;</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n        user<span class=\"o\">.</span>password <span class=\"o\">=</span> hasher<span class=\"o\">.</span>encode_sha1_hash<span class=\"p\">(</span>sha1_hash<span class=\"p\">,</span> salt<span class=\"p\">)</span>\n        user<span class=\"o\">.</span>save<span class=\"p\">(</span>update_fields<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;password&#39;</span><span class=\"p\">])</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;accounts&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">),</span>\n        <span class=\"c1\"># replace this with the latest migration in contrib.auth</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;auth&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;####_migration_name&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>forwards_func<span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></figure>\n<p>Be aware that this migration will take on the order of several minutes for\nseveral thousand users, depending on the speed of your hardware.</p>\n<p>Finally, we'll add a <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> setting:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">mysite/settings.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code>PASSWORD_HASHERS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;accounts.hashers.PBKDF2WrappedSHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Include any other hashers that your site uses in this list.</p>\n</section>\n<section id=\"included-hashers\">\n<span id=\"auth-included-hashers\"></span><h3>Included hashers<a class=\"heading-anchor\" href=\"#included-hashers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The full list of hashers included in Django is:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"p\">[</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.Argon2PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptSHA256PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.BCryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.ScryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.SHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.MD5PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.UnsaltedMD5PasswordHasher&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth.hashers.CryptPasswordHasher&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>The corresponding algorithm names are:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">pbkdf2_sha256</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">pbkdf2_sha1</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">argon2</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">bcrypt_sha256</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">bcrypt</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">scrypt</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">sha1</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">md5</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">unsalted_sha1</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">unsalted_md5</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">crypt</code></p></li>\n</ul>\n</section>\n<section id=\"writing-your-own-hasher\">\n<span id=\"write-your-own-password-hasher\"></span><h3>Writing your own hasher<a class=\"heading-anchor\" href=\"#writing-your-own-hasher\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you write your own password hasher that contains a work factor such as a\nnumber of iterations, you should implement a\n<code class=\"docutils literal notranslate\">harden_runtime(self, password, encoded)</code> method to bridge the runtime gap\nbetween the work factor supplied in the <code class=\"docutils literal notranslate\">encoded</code> password and the default\nwork factor of the hasher. This prevents a user enumeration timing attack due\nto  difference between a login request for a user with a password encoded in an\nolder number of iterations and a nonexistent user (which runs the default\nhasher's default number of iterations).</p>\n<p>Taking PBKDF2 as example, if <code class=\"docutils literal notranslate\">encoded</code> contains 20,000 iterations and the\nhasher's default <code class=\"docutils literal notranslate\">iterations</code> is 30,000, the method should run <code class=\"docutils literal notranslate\">password</code>\nthrough another 10,000 iterations of PBKDF2.</p>\n<p>If your hasher doesn't have a work factor, implement the method as a no-op\n(<code class=\"docutils literal notranslate\">pass</code>).</p>\n</section>\n</section>\n<section id=\"module-django.contrib.auth.hashers\">\n<span id=\"manually-managing-a-user-s-password\"></span><h2>Manually managing a user's password<a class=\"heading-anchor\" href=\"#module-django.contrib.auth.hashers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>The <a class=\"reference internal\" href=\"#module-django.contrib.auth.hashers\" title=\"django.contrib.auth.hashers\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth.hashers</code></a> module provides a set of functions\nto create and validate hashed passwords. You can use them independently\nfrom the <code class=\"docutils literal notranslate\">User</code> model.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.hashers.check_password\">\n<span class=\"sig-name descname\">check_password</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password</em>, <em class=\"sig-param\">encoded</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.hashers.check_password\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>If you'd like to manually authenticate a user by comparing a plain-text\npassword to the hashed password in the database, use the convenience\nfunction <a class=\"reference internal\" href=\"#django.contrib.auth.hashers.check_password\" title=\"django.contrib.auth.hashers.check_password\"><code class=\"xref py py-func docutils literal notranslate\">check_password()</code></a>. It takes two arguments: the plain-text\npassword to check, and the full value of a user's <code class=\"docutils literal notranslate\">password</code> field in the\ndatabase to check against, and returns <code class=\"docutils literal notranslate\">True</code> if they match, <code class=\"docutils literal notranslate\">False</code>\notherwise.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.hashers.make_password\">\n<span class=\"sig-name descname\">make_password</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password</em>, <em class=\"sig-param\">salt<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">hasher<span class=\"o\">=</span><span class=\"default_value\">'default'</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.hashers.make_password\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Creates a hashed password in the format used by this application. It takes\none mandatory argument: the password in plain-text (string or bytes).\nOptionally, you can provide a salt and a hashing algorithm to use, if you\ndon't want to use the defaults (first entry of <code class=\"docutils literal notranslate\">PASSWORD_HASHERS</code>\nsetting). See <a class=\"reference internal\" href=\"#auth-included-hashers\"><span class=\"std std-ref\">Included hashers</span></a> for the algorithm name of each\nhasher. If the password argument is <code class=\"docutils literal notranslate\">None</code>, an unusable password is\nreturned (one that will never be accepted by <a class=\"reference internal\" href=\"#django.contrib.auth.hashers.check_password\" title=\"django.contrib.auth.hashers.check_password\"><code class=\"xref py py-func docutils literal notranslate\">check_password()</code></a>).</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.hashers.is_password_usable\">\n<span class=\"sig-name descname\">is_password_usable</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">encoded_password</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.hashers.is_password_usable\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Returns <code class=\"docutils literal notranslate\">False</code> if the password is a result of\n<a class=\"reference internal\" href=\"/ja/4.0/ref/contrib/auth/#django.contrib.auth.models.User.set_unusable_password\" title=\"django.contrib.auth.models.User.set_unusable_password\"><code class=\"xref py py-meth docutils literal notranslate\">User.set_unusable_password()</code></a>.</p>\n</dd></dl>\n\n</section>\n<section id=\"module-django.contrib.auth.password_validation\">\n<span id=\"id3\"></span><span id=\"password-validation\"></span><h2>パスワードの妥当性検証<a class=\"heading-anchor\" href=\"#module-django.contrib.auth.password_validation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Users often choose poor passwords. To help mitigate this problem, Django\noffers pluggable password validation. You can configure multiple password\nvalidators at the same time. A few validators are included in Django, but you\ncan write your own as well.</p>\n<p>各パスワードのバリデータは、ユーザーに要件の説明文を与え、指定されたパスワードの妥当性検証を行い、要件を満たしていない場合はエラーメッセージを返し、必要に応じて設定されたパスワードを受信します。バリデータは、それらの挙動を微調整するオプション設定を持つこともできます。</p>\n<p>Validation is controlled by the <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a> setting.\nThe default for the setting is an empty list, which means no validators are\napplied. In new projects created with the default <a class=\"reference internal\" href=\"/ja/4.0/ref/django-admin/#django-admin-startproject\"><code class=\"xref std std-djadmin docutils literal notranslate\">startproject</code></a>\ntemplate, a set of validators is enabled by default.</p>\n<p>By default, validators are used in the forms to reset or change passwords and\nin the <a class=\"reference internal\" href=\"/ja/4.0/ref/django-admin/#django-admin-createsuperuser\"><code class=\"xref std std-djadmin docutils literal notranslate\">createsuperuser</code></a> and <a class=\"reference internal\" href=\"/ja/4.0/ref/django-admin/#django-admin-changepassword\"><code class=\"xref std std-djadmin docutils literal notranslate\">changepassword</code></a> management\ncommands. Validators aren't applied at the model level, for example in\n<code class=\"docutils literal notranslate\">User.objects.create_user()</code> and <code class=\"docutils literal notranslate\">create_superuser()</code>, because we assume\nthat developers, not users, interact with Django at that level and also because\nmodel validation doesn't automatically run as part of creating models.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>パスワードの妥当性検証は多くの脆弱なパスワードの形式が使用されることを防ぎます。しかしながら、パスワードが全てのバリデータを通過するという事実は、強力なパスワードであることを保証するわけではありません。最も先進的なパスワードのバリデータでさえ検出できない、パスワードを弱めうる多くの要素があります。</p>\n</aside>\n<section id=\"enabling-password-validation\">\n<h3>パスワードの妥当性検証を有効にする<a class=\"heading-anchor\" href=\"#enabling-password-validation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>パスワードの妥当性検証は <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a> で構成されます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code>AUTH_PASSWORD_VALIDATORS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.contrib.auth.password_validation.UserAttributeSimilarityValidator&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.contrib.auth.password_validation.MinimumLengthValidator&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;min_length&#39;</span><span class=\"p\">:</span> <span class=\"mi\">9</span><span class=\"p\">,</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">},</span>\n    <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.contrib.auth.password_validation.CommonPasswordValidator&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.contrib.auth.password_validation.NumericPasswordValidator&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>本例では組み込みの4つ全てのバリデータを有効化します。</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">UserAttributeSimilarityValidator</code> は、パスワードとユーザの属性との類似性をチェックします。</p></li>\n<li><p><code class=\"docutils literal notranslate\">MinimumLengthValidator</code>, which checks whether the password meets a minimum\nlength. This validator is configured with a custom option: it now requires\nthe minimum length to be nine characters, instead of the default eight.</p></li>\n<li><p><code class=\"docutils literal notranslate\">CommonPasswordValidator</code>, which checks whether the password occurs in a\nlist of common passwords. By default, it compares to an included list of\n20,000 common passwords.</p></li>\n<li><p><code class=\"docutils literal notranslate\">NumericPasswordValidator</code> は、パスワードが全体的に数値ではないかをチェックします。</p></li>\n</ul>\n<p>For <code class=\"docutils literal notranslate\">UserAttributeSimilarityValidator</code> and <code class=\"docutils literal notranslate\">CommonPasswordValidator</code>,\nwe're using the default settings in this example. <code class=\"docutils literal notranslate\">NumericPasswordValidator</code>\nhas no settings.</p>\n<p>The help texts and any errors from password validators are always returned in\nthe order they are listed in <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a>.</p>\n</section>\n<section id=\"included-validators\">\n<h3>Included validators<a class=\"heading-anchor\" href=\"#included-validators\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django includes four validators:</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.MinimumLengthValidator\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">MinimumLengthValidator</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">min_length<span class=\"o\">=</span><span class=\"default_value\">8</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.MinimumLengthValidator\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Validates whether the password meets a minimum length.\nThe minimum length can be customized with the <code class=\"docutils literal notranslate\">min_length</code> parameter.</p>\n</dd></dl>\n\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">UserAttributeSimilarityValidator</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">user_attributes<span class=\"o\">=</span><span class=\"default_value\">DEFAULT_USER_ATTRIBUTES</span></em>, <em class=\"sig-param\">max_similarity<span class=\"o\">=</span><span class=\"default_value\">0.7</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.UserAttributeSimilarityValidator\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Validates whether the password is sufficiently different from certain\nattributes of the user.</p>\n<p>The <code class=\"docutils literal notranslate\">user_attributes</code> parameter should be an iterable of names of user\nattributes to compare to. If this argument is not provided, the default\nis used: <code class=\"docutils literal notranslate\">'username', 'first_name', 'last_name', 'email'</code>.\nAttributes that don't exist are ignored.</p>\n<p>The maximum allowed similarity of passwords can be set on a scale of 0.1\nto 1.0 with the <code class=\"docutils literal notranslate\">max_similarity</code> parameter. This is compared to the\nresult of <a class=\"reference external\" href=\"https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.quick_ratio\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\">difflib.SequenceMatcher.quick_ratio()</code></a>. A value of 0.1\nrejects passwords unless they are substantially different from the\n<code class=\"docutils literal notranslate\">user_attributes</code>, whereas a value of 1.0 rejects only passwords that are\nidentical to an attribute's value.</p>\n<aside class=\"version-note version-changed\" data-version=\"2.2.26\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 2.2.26</p><p>The <code class=\"docutils literal notranslate\">max_similarity</code> parameter was limited to a minimum value of 0.1.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.CommonPasswordValidator\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">CommonPasswordValidator</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password_list_path<span class=\"o\">=</span><span class=\"default_value\">DEFAULT_PASSWORD_LIST_PATH</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.CommonPasswordValidator\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Validates whether the password is not a common password. This converts the\npassword to lowercase (to do a case-insensitive comparison) and checks it\nagainst a list of 20,000 common password created by <a class=\"reference external\" href=\"https://gist.github.com/roycewilliams/281ce539915a947a23db17137d91aeb7\">Royce Williams</a>.</p>\n<p>The <code class=\"docutils literal notranslate\">password_list_path</code> can be set to the path of a custom file of\ncommon passwords. This file should contain one lowercase password per line\nand may be plain text or gzipped.</p>\n</dd></dl>\n\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.NumericPasswordValidator\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">NumericPasswordValidator</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.NumericPasswordValidator\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Validates whether the password is not entirely numeric.</p>\n</dd></dl>\n\n</section>\n<section id=\"integrating-validation\">\n<h3>Integrating validation<a class=\"heading-anchor\" href=\"#integrating-validation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>There are a few functions in <code class=\"docutils literal notranslate\">django.contrib.auth.password_validation</code> that\nyou can call from your own forms or other code to integrate password\nvalidation. This can be useful if you use custom forms for password setting,\nor if you have API calls that allow passwords to be set, for example.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.validate_password\">\n<span class=\"sig-name descname\">validate_password</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password</em>, <em class=\"sig-param\">user<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">password_validators<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.validate_password\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Validates a password. If all validators find the password valid, returns\n<code class=\"docutils literal notranslate\">None</code>. If one or more validators reject the password, raises a\n<a class=\"reference internal\" href=\"/ja/4.0/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\">ValidationError</code></a> with all the error messages\nfrom the validators.</p>\n<p>The <code class=\"docutils literal notranslate\">user</code> object is optional: if it's not provided, some validators may\nnot be able to perform any validation and will accept any password.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.password_changed\">\n<span class=\"sig-name descname\">password_changed</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password</em>, <em class=\"sig-param\">user<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">password_validators<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.password_changed\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Informs all validators that the password has been changed. This can be used\nby validators such as one that prevents password reuse. This should be\ncalled once the password has been successfully changed.</p>\n<p>For subclasses of <a class=\"reference internal\" href=\"/ja/4.0/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\">AbstractBaseUser</code></a>,\nthe password field will be marked as &quot;dirty&quot; when calling\n<a class=\"reference internal\" href=\"/ja/4.0/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser.set_password\" title=\"django.contrib.auth.models.AbstractBaseUser.set_password\"><code class=\"xref py py-meth docutils literal notranslate\">set_password()</code></a> which\ntriggers a call to <code class=\"docutils literal notranslate\">password_changed()</code> after the user is saved.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.password_validators_help_texts\">\n<span class=\"sig-name descname\">password_validators_help_texts</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password_validators<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.password_validators_help_texts\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Returns a list of the help texts of all validators. These explain the\npassword requirements to the user.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.password_validators_help_text_html\">\n<span class=\"sig-name descname\">password_validators_help_text_html</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">password_validators<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.password_validators_help_text_html\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Returns an HTML string with all help texts in an <code class=\"docutils literal notranslate\">&lt;ul&gt;</code>. This is\nhelpful when adding password validation to forms, as you can pass the\noutput directly to the <code class=\"docutils literal notranslate\">help_text</code> parameter of a form field.</p>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.password_validation.get_password_validators\">\n<span class=\"sig-name descname\">get_password_validators</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">validator_config</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.password_validation.get_password_validators\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Returns a set of validator objects based on the <code class=\"docutils literal notranslate\">validator_config</code>\nparameter. By default, all functions use the validators defined in\n<a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a>, but by calling this function with an\nalternate set of validators and then passing the result into the\n<code class=\"docutils literal notranslate\">password_validators</code> parameter of the other functions, your custom set\nof validators will be used instead. This is useful when you have a typical\nset of validators to use for most scenarios, but also have a special\nsituation that requires a custom set. If you always use the same set\nof validators, there is no need to use this function, as the configuration\nfrom <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a> is used by default.</p>\n<p>The structure of <code class=\"docutils literal notranslate\">validator_config</code> is identical to the\nstructure of <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a>. The return value of\nthis function can be passed into the <code class=\"docutils literal notranslate\">password_validators</code> parameter\nof the functions listed above.</p>\n</dd></dl>\n\n<p>Note that where the password is passed to one of these functions, this should\nalways be the clear text password - not a hashed password.</p>\n</section>\n<section id=\"writing-your-own-validator\">\n<h3>Writing your own validator<a class=\"heading-anchor\" href=\"#writing-your-own-validator\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If Django's built-in validators are not sufficient, you can write your own\npassword validators. Validators have a fairly small interface. They must\nimplement two methods:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">validate(self, password, user=None)</code>: validate a password. Return\n<code class=\"docutils literal notranslate\">None</code> if the password is valid, or raise a\n<a class=\"reference internal\" href=\"/ja/4.0/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\">ValidationError</code></a> with an error message if the\npassword is not valid. You must be able to deal with <code class=\"docutils literal notranslate\">user</code> being\n<code class=\"docutils literal notranslate\">None</code> - if that means your validator can't run, return <code class=\"docutils literal notranslate\">None</code> for no\nerror.</p></li>\n<li><p><code class=\"docutils literal notranslate\">get_help_text()</code>: provide a help text to explain the requirements to\nthe user.</p></li>\n</ul>\n<p>Any items in the <code class=\"docutils literal notranslate\">OPTIONS</code> in <a class=\"reference internal\" href=\"/ja/4.0/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a> for your\nvalidator will be passed to the constructor. All constructor arguments should\nhave a default value.</p>\n<p>Here's a basic example of a validator, with one optional setting:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.core.exceptions</span> <span class=\"kn\">import</span> ValidationError\n<span class=\"kn\">from</span> <span class=\"nn\">django.utils.translation</span> <span class=\"kn\">import</span> gettext <span class=\"k\">as</span> _\n\n<span class=\"k\">class</span> <span class=\"nc\">MinimumLengthValidator</span><span class=\"p\">:</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> min_length<span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>min_length <span class=\"o\">=</span> min_length\n\n    <span class=\"k\">def</span> <span class=\"nf\">validate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> password<span class=\"p\">,</span> user<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span>password<span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span>min_length<span class=\"p\">:</span>\n            <span class=\"k\">raise</span> ValidationError<span class=\"p\">(</span>\n                _<span class=\"p\">(</span><span class=\"s2\">&quot;This password must contain at least </span><span class=\"si\">%(min_length)d</span><span class=\"s2\"> characters.&quot;</span><span class=\"p\">),</span>\n                code<span class=\"o\">=</span><span class=\"s1\">&#39;password_too_short&#39;</span><span class=\"p\">,</span>\n                params<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;min_length&#39;</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span>min_length<span class=\"p\">},</span>\n            <span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_help_text</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> _<span class=\"p\">(</span>\n            <span class=\"s2\">&quot;Your password must contain at least </span><span class=\"si\">%(min_length)d</span><span class=\"s2\"> characters.&quot;</span>\n            <span class=\"o\">%</span> <span class=\"p\">{</span><span class=\"s1\">&#39;min_length&#39;</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span>min_length<span class=\"p\">}</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n<p>You can also implement <code class=\"docutils literal notranslate\">password_changed(password, user=None</code>), which will\nbe called after a successful password change. That can be used to prevent\npassword reuse, for example. However, if you decide to store a user's previous\npasswords, you should never do so in clear text.</p>\n</section>\n</section>","rootId":"password-management-in-django","toc":[{"title":"Djangoのパスワード保存方法","anchor":"how-django-stores-passwords","children":[{"title":"Using Argon2 with Django","anchor":"using-argon2-with-django","children":[]},{"title":"Using bcrypt with Django","anchor":"using-bcrypt-with-django","children":[]},{"title":"Using scrypt with Django","anchor":"using-scrypt-with-django","children":[]},{"title":"Increasing the salt entropy","anchor":"increasing-the-salt-entropy","children":[]},{"title":"Increasing the work factor","anchor":"increasing-the-work-factor","children":[{"title":"PBKDF2 and bcrypt","anchor":"pbkdf2-and-bcrypt","children":[]},{"title":"Argon2","anchor":"argon2","children":[]},{"title":"scrypt","anchor":"scrypt","children":[]}]},{"title":"パスワードの更新","anchor":"password-upgrading","children":[]},{"title":"Password upgrading without requiring a login","anchor":"password-upgrading-without-requiring-a-login","children":[]},{"title":"Included hashers","anchor":"included-hashers","children":[]},{"title":"Writing your own hasher","anchor":"writing-your-own-hasher","children":[]}]},{"title":"Manually managing a user's password","anchor":"module-django.contrib.auth.hashers","children":[]},{"title":"パスワードの妥当性検証","anchor":"module-django.contrib.auth.password_validation","children":[{"title":"パスワードの妥当性検証を有効にする","anchor":"enabling-password-validation","children":[]},{"title":"Included validators","anchor":"included-validators","children":[]},{"title":"Integrating validation","anchor":"integrating-validation","children":[]},{"title":"Writing your own validator","anchor":"writing-your-own-validator","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/4.0/topics/"},{"docname":"topics/auth/index","title":"Django でのユーザー認証","url":"/ja/4.0/topics/auth/"}],"prev":{"docname":"topics/auth/default","title":"Djangoの認証システムを使用する","url":"/ja/4.0/topics/auth/default/"},"next":{"docname":"topics/auth/customizing","title":"Django の認証方法のカスタマイズ","url":"/ja/4.0/topics/auth/customizing/"},"formats":{"html":"/ja/4.0/topics/auth/passwords/","markdown":"/ja/4.0/topics/auth/passwords.md","json":"/ja/4.0/topics/auth/passwords.json"},"source":"https://github.com/django/django/blob/stable/4.0.x/docs/topics/auth/passwords.txt","official":"https://docs.djangoproject.com/ja/4.0/topics/auth/passwords/","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","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}