[アルゴリズム]暗号結果から、類似パスワードのを推測困難にする方法

ある文字列に一定の法則で(bit単位かき混ぜること)をスクランブルといいます。
また、特定の文字列を一定の法則で取り出した物や、暗号化した出力結果をデータのハッシュ値といいます。

ハッシュにも色々な種類があって、元の情報量より情報量が減り、復元不可能なものや、元の情報が違うのに同じハッシュ値になるもの(ハッシュ衝突と言います)や、実行のたびに値が変わるものなど、様々です。


さて、可逆性のあるハッシュによる暗号化をパスワードに使用した場合、同じパスワードから同じ値のハッシュ値が返ってくるアルゴリズムがほとんどです。

これだと、アルゴリズムさえわかってしまえば、予め、予測した文字列でハッシュ値を生成しておいて、パスワードハッシュとの比較を行って、一致するものがあれば、パスワードが分かってしまうという、ブルートフォース攻撃の脆弱性がありますね。

そこで、暗号化する文字列の頭数バイトに不定値を放り込む仕様にします。

   char instr[100];
   long tm;
   int t;
   time( (long*)&instr);
   lstrcpy(instr+4,inputstring);
   t=Encode(instr,lstrlen(instr+4)+4);

復号するときは、頭の数バイトを無視します

   long tm;
   int t;
   t=Decode(instr,len);
   instr[t]=0;
   lstrcpy(outstr,instr+4);

Encode 処理の概要です。

    HCRYPTHASH    hHash;
    HCRYPTKEY    hKey;

    if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)){
        return 0;
    }
    if(!CryptHashData(hHash,(BYTE*)passstr,passlen, 0)){
        return 0;
    }
    if(!CryptDeriveKey(hProv, CALG_RC4, hHash, KEYLENGTH_128, &hKey)){

        return 0;
    }
    if(!CryptEncrypt(hKey, 0, true, 0, buf, &inlen, inlen)){
        return 0;
    }
    if(!CryptDestroyKey(hKey)){
        return 0;
    }
    if (!CryptDeriveKey(hProv, CALG_RC2, hHash, CRYPT_EXPORTABLE, &hKey)) {
        return 0;
    }
    if(!CryptEncrypt(hKey, 0, TRUE, 0, buf, &inlen, 1024/*Buffersize*/)){
        return 0;
    }
    if(!CryptDestroyHash(hHash)){
        return 0;
    }
    if(!CryptDestroyKey(hKey)){
        return 0;
    }

暗号化には、ブロック暗号とストリーム暗号を組み合わせます。

    HCRYPTHASH    hHash;
    HCRYPTKEY    hKey;

    if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)){
        return 0;
    }
    if(!CryptHashData(hHash,(BYTE*)passstr,passlen, 0)){
        return 0;
    }
    if (!CryptDeriveKey(hProv, CALG_RC2, hHash, CRYPT_EXPORTABLE, &hKey)) {
        return 0;
    }
    if(!CryptDecrypt(hKey, 0, TRUE, 0, buf, &strlen)){
        return 0;
    }
    if(!CryptDestroyKey(hKey)){
        return 0;
    }
    if(!CryptDeriveKey(hProv, CALG_RC4, hHash,KEYLENGTH_128, &hKey)){
        return 0;
    }
    if(!CryptDecrypt(hKey, 0, TRUE, 0, buf, &strlen)){
        return 0;
    }
    if(!CryptDestroyHash(hHash)){
        return 0;
    }
    if(!CryptDestroyKey(hKey)){
        return 0;
    }

復号は逆の処理をやっているだけです。

結構簡単ですね|・ω・)ノ ?
元のデータが1文字違うだけでも、作成した暗号化したデータが全然変わると、同じデータでも時間ごとに値が違うのが特徴です。

関連サイト:
簡単な暗号化 - 共通鍵暗号化

おすすめ

12件のフィードバック

  1. より:

    突っ込みどころが多すぎると思います。
    ハッシュと可逆について調べてみたらどうでしょうか?

  2. より:

    突っ込みどころが多すぎると思います。
    ハッシュと可逆について調べてみたらどうでしょうか?

  3. より:

    突っ込みどころが多すぎると思います。
    ハッシュと可逆について調べてみたらどうでしょうか?

  4. blackwingcat より:

    ありがとうございます。
    昔、下書きで書いた冒頭説明とタイトル修正するの忘れて、そのままアップしてしまいました。
    今、見てみると、確かに内容めちゃくちゃですね(汗)
    アップし直したのが、現在の私の認識ですがおかしいところがあれば突っ込んでください

  5. blackwingcat より:

    ありがとうございます。
    昔、下書きで書いた冒頭説明とタイトル修正するの忘れて、そのままアップしてしまいました。
    今、見てみると、確かに内容めちゃくちゃですね(汗)
    アップし直したのが、現在の私の認識ですがおかしいところがあれば突っ込んでください

  6. blackwingcat より:

    ありがとうございます。
    昔、下書きで書いた冒頭説明とタイトル修正するの忘れて、そのままアップしてしまいました。
    今、見てみると、確かに内容めちゃくちゃですね(汗)
    アップし直したのが、現在の私の認識ですがおかしいところがあれば突っ込んでください

  7. より:

    長文になりますが、
    この記事を読んで間違って覚える人がいないとも言えないので、
    突っ込みどころ1つずつ挙げていきましょうか。
    まずこれは確認ですが、
    この記事全体として、やりたいことは何なんでしょうか?
    鯖上で認証に用いるパスの保持をハッシュで行うということなのであれば、
    鯖上にパスが復元できる”可逆な”データを置いておくのは意味が無いかと思われます。
    以下突っ込み
    >暗号化した出力結果をデータのハッシュ値といいます。
    暗号化とハッシュは別物です。
    >ハッシュにも色々な種類があって、元の情報量より情報量が減り、復元不可能なもの
    ハッシュ値は固定長なので全てそうなります。
    >実行のたびに値が変わるもの
    これはソルトを付加しているため値が変わっていると考えられます。
    ハッシュ関数自体としては同じ値を吐いています。
    >可逆性のあるハッシュによる暗号化をパスワードに使用した場合、同じパスワードから同じ値のハッシュ値が返ってくるアルゴリズムがほとんど
    前述通りハッシュは不可逆ですが、
    ハッシュではなく可逆なエンコードとして考えた場合でも、
    同じアルゴリズム、同じ条件で行えば”絶対に”同じ値が返ってきます。
    可逆である以上入力データと出力データは1対1になります。
    その為、入力データにソルトを付加し出力データが同一にならないようにするのです。
    >予測した文字列でハッシュ値を生成しておいて
    予測したデータを用いる場合ブルートフォースではありません。
    以上です。

  8. より:

    長文になりますが、
    この記事を読んで間違って覚える人がいないとも言えないので、
    突っ込みどころ1つずつ挙げていきましょうか。
    まずこれは確認ですが、
    この記事全体として、やりたいことは何なんでしょうか?
    鯖上で認証に用いるパスの保持をハッシュで行うということなのであれば、
    鯖上にパスが復元できる”可逆な”データを置いておくのは意味が無いかと思われます。
    以下突っ込み
    >暗号化した出力結果をデータのハッシュ値といいます。
    暗号化とハッシュは別物です。
    >ハッシュにも色々な種類があって、元の情報量より情報量が減り、復元不可能なもの
    ハッシュ値は固定長なので全てそうなります。
    >実行のたびに値が変わるもの
    これはソルトを付加しているため値が変わっていると考えられます。
    ハッシュ関数自体としては同じ値を吐いています。
    >可逆性のあるハッシュによる暗号化をパスワードに使用した場合、同じパスワードから同じ値のハッシュ値が返ってくるアルゴリズムがほとんど
    前述通りハッシュは不可逆ですが、
    ハッシュではなく可逆なエンコードとして考えた場合でも、
    同じアルゴリズム、同じ条件で行えば”絶対に”同じ値が返ってきます。
    可逆である以上入力データと出力データは1対1になります。
    その為、入力データにソルトを付加し出力データが同一にならないようにするのです。
    >予測した文字列でハッシュ値を生成しておいて
    予測したデータを用いる場合ブルートフォースではありません。
    以上です。

  9. より:

    長文になりますが、
    この記事を読んで間違って覚える人がいないとも言えないので、
    突っ込みどころ1つずつ挙げていきましょうか。
    まずこれは確認ですが、
    この記事全体として、やりたいことは何なんでしょうか?
    鯖上で認証に用いるパスの保持をハッシュで行うということなのであれば、
    鯖上にパスが復元できる”可逆な”データを置いておくのは意味が無いかと思われます。
    以下突っ込み
    >暗号化した出力結果をデータのハッシュ値といいます。
    暗号化とハッシュは別物です。
    >ハッシュにも色々な種類があって、元の情報量より情報量が減り、復元不可能なもの
    ハッシュ値は固定長なので全てそうなります。
    >実行のたびに値が変わるもの
    これはソルトを付加しているため値が変わっていると考えられます。
    ハッシュ関数自体としては同じ値を吐いています。
    >可逆性のあるハッシュによる暗号化をパスワードに使用した場合、同じパスワードから同じ値のハッシュ値が返ってくるアルゴリズムがほとんど
    前述通りハッシュは不可逆ですが、
    ハッシュではなく可逆なエンコードとして考えた場合でも、
    同じアルゴリズム、同じ条件で行えば”絶対に”同じ値が返ってきます。
    可逆である以上入力データと出力データは1対1になります。
    その為、入力データにソルトを付加し出力データが同一にならないようにするのです。
    >予測した文字列でハッシュ値を生成しておいて
    予測したデータを用いる場合ブルートフォースではありません。
    以上です。

  10. blackwingcat より:

    この記事で書いたのは、復元可能なデータの暗号化で、
    暗号化・復号のサンプル関数を使うと、暗号化したときに毎回同じ出力が
    出てくるので、それをパスワードを暗号化したときにハッシュ値が同じに
    なる話に絡めてソルト値をパスワードに付加して書くとしたら、と言う
    実験のつもりでした。
    ありがとうございます。

  11. blackwingcat より:

    この記事で書いたのは、復元可能なデータの暗号化で、
    暗号化・復号のサンプル関数を使うと、暗号化したときに毎回同じ出力が
    出てくるので、それをパスワードを暗号化したときにハッシュ値が同じに
    なる話に絡めてソルト値をパスワードに付加して書くとしたら、と言う
    実験のつもりでした。
    ありがとうございます。

  12. blackwingcat より:

    この記事で書いたのは、復元可能なデータの暗号化で、
    暗号化・復号のサンプル関数を使うと、暗号化したときに毎回同じ出力が
    出てくるので、それをパスワードを暗号化したときにハッシュ値が同じに
    なる話に絡めてソルト値をパスワードに付加して書くとしたら、と言う
    実験のつもりでした。
    ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です