Linuxは、新しいパスワードが以前のパスワードと似ていることをどのように知っていますか?


145

数回、さまざまなLinuxマシンでユーザーのパスワードを変更しようとしましたが、新しいパスワードが古いパスワードと似ている場合、OSはそれらがあまりにも似ていると不満を言いました。

システムはこれをどのように知っているのでしょうか?パスワードはハッシュとして保存されると思いました。これは、システムが新しいパスワードの類似性を比較できる場合、古いパスワードが実際にプレーンテキストとして保存されることを意味しますか?


30
1回目:プレーンテキストですか?番号。保存した場合、ハッシュを保存してハッシュを比較します。Linuxでは、現在のパスワードと新しいパスワードをチェックします。両方とも、パスワードを変更するときにユーザーによって提供されます。
リンツウィンド14

42
@Rinzwindしかし、1つの文字の違いは完全に異なるハッシュを生じるはずであるので、比較するハッシュは動作しません
slhck

17
Facebookはプレーンテキストのパスワード保存しますか?もご覧ください古いパスワードのハッシュと新しいパスワードのプレーンテキストのみを指定して類似性を検出する他の方法については、情報セキュリティについて(古いテキストのプレーンテキストはありません)。
ボブ14

21
実際に、ハッシュされた古いパスワードとプレーンテキストの新しいパスワードの類似性をテストできます。新しいパスワードと同様のパスワードのリストを生成し、それらをすべてハッシュし、結果のハッシュを古いパスワードハッシュと比較します。一致する場合は、同様です。
BWG 14

2
@BWG:これは少し単純化しすぎています。現在のハッシュスキームはハッシュをソルトするため、最初に古いパスワードハッシュからソルトを抽出し、新しいソルトと同じパスワードにそのソルトを使用する必要があります。(APIが特定のソルトを強制する方法を公開しない可能性があるため、これを指摘しています。)
Ulrich Schwarz

回答:


156

を使用する場合、古いパスワード新しいパスワードの両方を提供する必要があるためpasswd、ドライブ上のどこかに書き込むことなく、メモリ内のプレーンテキストで簡単に比較できます。

実際、パスワードは最終的に保存されるときにハッシュされますが、それが起こるまで、パスワードを入力しているツールはもちろん、他のプログラムがSTDINから読み込んでいる間にキーボードで入力したものにアクセスできるように直接アクセスできます。

これは、ツールのバックグラウンドで使用されるPAMシステムの機能passwdです。PAMは、最新のLinuxディストリビューションで使用されています。

より具体的にpam_cracklibは、PAMのモジュールであり、パスワードを非常に脆弱にするいくつかの弱点に基づいてパスワードを拒否できます。

安全ではないと考えられるのは、パスワードが似ているだけではありません。ソースコードは、 パスワードは回文または何編集距離は、二つの単語の間にあるかどうかを確認することができます例えば何の様々な例を、持っています。この考え方は、辞書攻撃に対するパスワードの耐性を高めることです。

参照してくださいmanページを。pam_cracklib


あなたの説明が私の答えで報告された議論に「どのように」適合するかについてのアイデアはありますか?ホストがPAMに対応していない場合、「passwd」アプリケーションで使用される2つの異なるアプローチはありますか?PS:批評家はまったくいません。私はただ疑問に思っています(PAM、BTWは私の最初の推測でした...ソースコードをgrepする直前)。
ダミアーノヴェルズリ14

27
さらに厄介なのは、最後の4つのパスワードのいずれかで同じまたは類似したパスワードを使用した場合に警告する企業パスワードルールです。
ニックT 14

4
@NickTどのように(必然的に)邪魔になるのですか?最後の4つのハッシュを保存してから、この質問と同じようにそれぞれを提案された新しいハッシュと比較できませんでしたか?
ネミネム

1
@neminem「...または類似」
ニックT 14

1
@NickTああ、結構です。この特定のケースでは、保存されたハッシュではなく、ユーザーがパスワードを変更するために入力した「古いパスワード」と比較しているからです。それでも、少なくとも単純な変更(1文字の置換、1文字の追加/削除など)を確認するために、コメントに投稿されたメソッドBWGを仮説的に使用できます。
ネミネム14

46

少なくとも私のUbuntuでは、「あまりにも似た」メッセージが出ました when:"...文字の半分以上が異なる文字です..."(詳細は以下を参照)。 @slhckの回答で明確に説明されているように、PAMサポートのおかげです。

:PAMが使用されていない他のプラットフォームについては、「似すぎ」のメッセージが出てくるとき「...複数の文字の半分以上異なるものです....」(詳細は下記を参照してください)

このステートメントを自分でさらに確認するには、ソースコードを確認することができます。方法は次のとおりです。

「passwd」プログラムは、passwdパッケージに含まれています。

verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd

オープンソース技術を扱っているため、ソースコードへの無制限のアクセスがあります。取得は次のように簡単です。

verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd

その後、関連するコードの断片を簡単に見つけることができます。

verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c:     msg = _("too similar");

「obscure.c」を簡単に確認すると、これがわかります(関連するコードのみをカットアンドペーストしています)。

static const char *password_check (
    const char *old,
    const char *new,
    const struct passwd *pwdp)
{
    const char *msg = NULL;
    char *oldmono, *newmono, *wrapped;

    if (strcmp (new, old) == 0) {
            return _("no change");
    }
    [...]
    if (palindrome (oldmono, newmono)) {
            msg = _("a palindrome");
    } else if (strcmp (oldmono, newmono) == 0) {
            msg = _("case changes only");
    } else if (similar (oldmono, newmono)) {
            msg = _("too similar");
    } else if (simple (old, new)) {
            msg = _("too simple");
    } else if (strstr (wrapped, newmono) != NULL) {
            msg = _("rotated");
    } else {
    }
    [...]
    return msg;
}

したがって、今では、古いものと新しいものの両方のチェックに基づいて、両方が類似しているかどうかに基づいた「類似の」関数があることがわかります。スニペットは次のとおりです。

/*
 * more than half of the characters are different ones.
 */
static bool similar (const char *old, const char *new)
{
    int i, j;

    /*
     * XXX - sometimes this fails when changing from a simple password
     * to a really long one (MD5).  For now, I just return success if
     * the new password is long enough.  Please feel free to suggest
     * something better...  --marekm
     */
    if (strlen (new) >= 8) {
            return false;
    }

    for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
            if (strchr (new, old[i]) != NULL) {
                    j++;
            }
    }

    if (i >= j * 2) {
            return false;
    }

    return true;
}

私はCコードをレビューしていません。関数定義の直前のコメントを信頼することに自分自身を制限しました:-)


PAMとNON-PAM対応プラットフォームの違いは、次のような構造の「obscure.c」ファイルで定義されています。

#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else                           /* !USE_PAM */
extern int errno;               /* warning: ANSI C forbids an empty source file */
#endif                          /* !USE_PAM */

9
これは長い答えであり、パスワードがハッシュされたときに古いパスワードとどのように比較できるかという質問には直接答えないようです。
ジェームズリン14

10
@jamesdlin:元の質問に対するRinzwindコメントで述べられているように、ハッシュはこの問題では何の役割も果たしません。パスワードを変更するために「passwd」コマンドを発行するとき、「古い」パスワードと「新しい」パスワードの両方を提供する必要があります。したがって、「passwd」コードは、両方のパスワードを一度に比較/チェックするのにまったく問題ありません(明確な形式で、まったくハッシュされません)。
ダミアーノヴェルズーリ14

3
@DamianoVerzulliそれにもかかわらず、これは本当に問題に対処していません。問題は「2つの文字列が似ているかどうかを判断するためにどのCコードを使用するか」ではありませんでした。パスワードについては、他の場合とまったく同じです。事パスワードそれらを面白くする彼らは平文で保存されることはありませんしていることであり、それは質問がについて尋ねるものです。これは「どの基準が使用され、Cでどのように実行されるか」と答えますが、「どの基準」と「Cでこれを行うか」はSOの質問であり、SUの質問ではありません。
cpast

7
@DamianoVerzulliそして、passwd古いパスワードと新しいパスワードの両方を要求するという事実が答えです。この答えの残りは無関係です。
ジェームズリン14

3
+1と非常に関連性の高い興味深い回答!パスワードを比較する実際のコードが、実際にはプレーンテキストで機能し、予想どおり、ハッシュでは機能しないことがわかります。
ニコ14

36

答えはあなたが思っているよりもはるかに簡単です。実際、トリックを説明すると、消えてしまうので、ほとんど魔法の資格があります。

$ passwd
Current Password:
New Password:
Repeat New Password:

Password changed successfully

新しいパスワードが似ていることがわかります...直前に古いパスワードを入力したためです。


2
「...またはキャンディ。」
ニックT 14

1
愚かなウサギ、トリックスは子供向けです!
iAdjunct 14

1
説明されていないのは、過去n個のパスワードを知っている場合です:)「パスワードが最近使用されすぎています」。これにより、企業環境で同じ数個のパスワードを交換できなくなります。
ユハウンティネン14

3
@Juha Untinen:それは事実ですが、それは最後のN個のハッシュを思い出すだけで処理できます。「N番目のパスワードと同じ」をキャッチするのは簡単で、「N番目のパスワードにている」のは難しいです。私が知っている限り、これらのシステムは最後のパスワードとの類似性、および最後のNとの同一性のみをチェックします。私は彼らがそれをどのように行うのか分かりません。
コートアンモン14

7

他の答えは正しいですが、これが機能するために古いパスワードを提供する必要はないことを言及する価値があります!

実際、提供された新しいパスワードに類似したパスワードの束を生成し、ハッシュし、これらのハッシュのいずれかが古いものと一致するかどうかを確認できます。この場合、新しいパスワードは古いパスワードと同様に判断されます!:)


2
これは確かにこの偉業を達成するための手段ですが(多くのWebサイトで使用されています)、それはこのインスタンスで起こっていることではありません。
ブライアンS 14

それはきちんとしたトリックです!ほんの少しだけ計算集約的ですが、賢い!
コートアンモン14

少なくとも、意味のあるチェック、または外部リソースへのリンクを得るために、いくつの同様のパスワードを生成する必要があるかについて、ある程度の推定値を与える必要があります。それ以外の場合、これは可能な代替案の単なるアイデアであり、実証された答えではありません。
ハイド14

誰かが考える基準に依存する@hyde。私にとってパスワードは、最大3文字が追加/削除/変更された場合に似ています。したがって、すべての文字に対して62個のハッシュ(英数字のみを使用する場合)とパスワードの長さ(n)からの3の組み合わせ、62 * (n!)/(6 * (n - 3)!)つまり12文字のパスワードに対して13540になります。しかし、誰かが何か違うことを考えると、方程式は役に立たないので、なぜわざわざ?
キラー

愚かな答えだが、それでも洞察力。なぜばか?1.想像を絶する数のハッシュを生成する必要があります。2.このようなセットアップは、元のパスワードのセキュリティを弱めます。誰かが1つだけのハッシュではなく、すべての同様のパスワードのハッシュを取得した場合、それを解読するのがはるかに簡単になります。
ロッククラリ

5

1つの側面はカバーされませんでした:パスワード履歴。一部のシステムはこれをサポートしています。そのために、パスワードの履歴を保持し、現在のパスワードで暗号化します。パスワードを変更すると、「古い」パスワードを使用してリストを復号化し、検証します。そして、新しいパスワードを設定すると、新しいパスワードから派生したキーで暗号化されたリストを(再び)保存します。

これがremember=NPAM(に保存/etc/security/opasswd)での動作です。しかし、Windowsや他のUnixベンダーも同様の機能を提供しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.