web-dev-qa-db-ja.com

使用されているエンコード/暗号化のタイプを確認するにはどうすればよいですか?

使用されている暗号化/エンコーディングのタイプを見つける方法はありますか?たとえば、データベースにパスワードを暗号化された形式で保存するWebアプリケーションをテストしています(WeJcFMQ/8+8QJ/w0hHh+0g==)。使用されているハッシュまたは暗号化を判別するにはどうすればよいですか?

156
Karthik

あなたの例の文字列(WeJcFMQ/8+8QJ/w0hHh+0g==)は、意味のあるASCIIまたはUTF-8のようには見えない)16バイトのシーケンスのBase64エンコーディングです。Ifこれはパスワード用に保存された値です- verification(つまり、実際には「暗号化された」パスワードではなく、「ハッシュされた」パスワード)次に、これはおそらくパスワードに対して計算されたハッシュ関数の結果です; 128ビット出力の1つの古典的なハッシュ関数MD5ですが、何でもかまいません。

これを知る「通常の」方法は、アプリケーションコードを調べることです。アプリケーションコードは具体的で太い方法(サーバー上の実行可能ファイル、どこかでのソースコードなど)で具体化されます。これは、秘密鍵のように保護することはできず、保護することもできません。したがって、リバースエンジニアリングは「進むべき道」です。

リバースエンジニアリングを除いて、いくつかの実験を行って、知識に基づいた推測を試みることができます。

  • 同じユーザーが自分のパスワードを「変更」したが、それを再利用した場合、保存された値は変更されますか?はいの場合、値の一部はおそらくランダム化された「塩」またはIV(対称暗号化を想定)です。
  • 値が特定のユーザーのパスワードから決定的であると仮定すると、2人のユーザーが同じパスワードを選択した場合、同じ値が格納されますか?いいえの場合、ユーザー名はおそらく計算の一部です。 MD5( "username:password")または他の同様のバリアントを計算して、一致するかどうかを確認することをお勧めします。
  • パスワードの長さは制限されていますか?つまり、40文字のパスワードを設定し、最初の39文字だけを入力しても認証に成功しない場合、これはすべての文字が重要であることを意味し、これは本当にパスワードであることを意味しますハッシュではなく- 暗号化(保存された値はパスワードの検証に使用されますが、保存された値のみからパスワードを回復することはできません)。
140
Thomas Pornin

編集: hashID という名前の非常にクールなスクリプトに気づきました。名前はそれをかなり説明しています。

~~~

一般的に言えば、経験を使って知識に基づいた推測を行うことが、これらのことを行う方法です。

これは非常に多数のハッシュ出力のリストであり、各出力がどのように見えるかを理解し、署名/パターンを作成するか、または単に光学的に検証します。

最初に注目する2つのmainがあります。

  • ハッシュの長さ(各ハッシュ関数には特定の出力長があります)
  • 使用されているアルファベット(すべて英字ですか?0〜9とA〜Fは16進数ですか?どんな特殊文字がありますか?)

いくつかのパスワードクラッキングプログラム(たとえば、John the ripper)は、使用されるアルゴリズムを推測するために入力にパターンマッチングを適用しますが、これは一般的なハッシュでのみ機能します。たとえば、ハッシュ出力を受け取り、各文字を1ずつローテーションすると、ほとんどのパターンマッチングスキームは失敗します。

68
john

あなたが投稿したのは、base 64エンコードデータの16バイト(128ビット)です。 Base 64でエンコードされているという事実は、Base 64が暗号化/ハッシュアルゴリズムではないため、バイナリデータをテキストにエンコードする方法であるため、あまりわかりません。つまり、このブロックには1つの有用な情報が含まれています。つまり、出力の長さは16バイトです。これを一般的に使用されるスキームのブロックサイズと比較して、それが何であり得ないかを理解できます。最も一般的なスキームは次のとおりです。

次に行う必要があるのは、暗号文の他のブロックを見て、次の質問に対する答えを理解することです。

  • 入力の長さが異なっていても、すべての暗号テキストは同じ長さですか?

すべてのブロックが同じ長さではない場合、ハッシュアルゴリズムではなく、暗号化アルゴリズムを検討しています。出力は常に基礎となるブロックサイズの倍数になるため、16バイトで均等に割り切れないブロックが存在する場合は、AESにできないため、DESまたは3DESである必要があります。

パスワードを入力して出力を確認する機能がある場合、これは非常に迅速に判断できます。 17文字のパスワードを入力して、長さを確認してください。その16バイトにMD5がある場合、20バイトはSHA-1を意味し、24バイトはDESまたは3DESを意味し、32バイトはAESを意味します。

26
Yaur

これが本当に単純なパスワードハッシュである場合、 Googleを使用してクラックする ができる可能性があります。ただし、Base64は検索が難しいため、スラッシュとプラス記号をすべて使用しているため、最初にそのハッシュを16進数に変換します。

$ Perl -MMIME::Base64 -le 'print unpack "H*", decode_base64 "WeJcFMQ/8+8QJ/w0hHh+0g=="'
59e25c14c43ff3ef1027fc3484787ed2

OK、これで Google for it ができます。現在、私は md5this.com から 1つのヒットのみ を取得しています。

残念ながら(おそらく幸いにも、あなたの見方によっては)、実際にプリイメージを見つけるには幸運ではありません(サイトは現在このハッシュを「クラッキング...」としてリストしています)が、そのリストにあるという事実はまったくそれは確かに実際のパスワードの無塩MD5ハッシュであることを強くお勧めします。

6
Ilmari Karonen

それはフォーマットに依存します-暗号化されたテキストを格納するためのいくつかのプロトコルは、それがどのように暗号化されるかを定義するクリアテキスト部分を持っています。あなたの例から、あなたが参照する文字列は非常に短いので、それが単なる暗号化されたテキストのように見えるので、私は疑わしいです。

私はいくつかの考えを提案します:

  • 最後の「==」は間違いなくパディングであるため、復号化の試行には含めないでください。

  • 暗号化ではなく、ハッシュまたはソルトハッシュを扱っている可能性があります。その場合、データを「復号化」しようとしても機能しません。元々使用されていたのと同じハッシュ値やソルト値を使用してパスワードを一致させる必要があります。ソルトされたパスワードを使用して元の値を取得する方法はありません。

  • 最善の策は、パスワードの保存に使用されるコードのコピーを入手することです。どこかで、パスワードは暗号化操作を受けています。ここで何が起こっているかを知るためのコードを見つけてください。 10回のうち9回は、ハッシュ/塩漬け/暗号化に何らかのAPIを使用しており、同じAPIを使用してそれを模倣または逆転できます。

6
bethlakshmi

エンコーディングは一般的に推測することができます。たとえば、質問に投稿した文字列はBase64でエンコードされています。等号は、Base64スキームではパディングです。それは経験から私が見ているものです。

暗号化された文字列を提供してくれた場合、エンコーディングを教えてもらえるかもしれませんが、なんらかのメタデータが利用可能でない限り、暗号化に使用したアルゴリズムはわかりません。その理由は、暗号化アルゴリズムはランダムデータのように見えるものを生成することによって機能するからです。それぞれ2つの暗号(4つの出力)で2つの文を暗号化した場合、暗号を解読したり暗号を解いたりしない限り、どの暗号テキストがどの暗号に属していたかを確信を持って知ることはできません。

特定のインスタンスに関しては、パスワードは通常ハッシュされます。つまり、ハッシュからパスワードを回復することはできませんが、ハッシュがパスワードと一致するかどうかをテストすることができます。その点で、 @ john's answer は黄金です。知っているパスワードを入力して、それに対する一般的なスキームを試すことができれば、使用されているハッシュが何であるかを知ることができます。

6
Jeff Ferland

唯一の方法は推測することです。経験があれば、作品はより正確になります。

例:出力の長さに基づく:MD5出力は128ビット(16バイト)、SHA1出力は160ビット(20バイト)。出力の文字セットに基づく:BASE64は、印刷可能な文字を含む出力を生成します。

結局のところ、その方法を教えるのは試行錯誤のアプローチです。

4
Nam Nguyen

これはあらゆる面で非常に弱いセキュリティです!平文はP4 $$ w0rdP4 $$ w0rdであり、XOR暗号化、キーCdZ4MLMPgYtAE9gQ80gMtg ==を使用して暗号化されます。これにより、上記のOPによって投稿された暗号文WeJcFMQ/8 + 8QJ/w0hHh + 0g ==

検証します:

まず、xxdを使用して平文の基礎となるバイナリを取得します。

echo -n 'P4$$w0rdP4$$w0rd' | xxd -b -c16

これにより、以下が生成されます。

01010000 00110100 00100100 00100100 01110111 00110000 01110010 01100100 01010000 00110100 00100100 00100100 01110111 00110000 01110010 01100100

次に、base64でキーをデコードし、xxdを使用してキーの基礎となるバイナリを取得します。

echo -n 'CdZ4MLMPgYtAE9gQ80gMtg==' | base64 -d | xxd -b -c16

これにより、以下が生成されます。

00001001 11010110 01111000 00110000 10110011 00001111 10000001 10001011 01000000 00010011 11011000 00010000 11110011 01001000 00001100 10110110

XOR 2つのバイナリ文字列:

01010000 00110100 00100100 00100100 01110111 00110000 01110010 01100100 01010000 00110100 00100100 00100100 01110111 00110000 01110010 01100100  (plaintext)
[XOR]
00001001 11010110 01111000 00110000 10110011 00001111 10000001 10001011 01000000 00010011 11011000 00010000 11110011 01001000 00001100 10110110  (key)
-----------------------------------------------------------------------------------------------------------------------------------------------
01011001 11100010 01011100 00010100 11000100 00111111 11110011 11101111 00010000 00100111 11111100 00110100 10000100 01111000 01111110 11010010  (ciphertext)

最後に、bc、xxd、およびbase64を使用して、バイナリ暗号文をbase64に変換します。

echo "obase=16; ibase=2; 01011001111000100101110000010100110001000011111111110011111011110001000000100111111111000011010010000100011110000111111011010010" | bc | xxd -p -r | base64

これによりWeJcFMQ/8 + 8QJ/w0hHh + 0g ==が生成されます。これは、上記の質問でOPによって投稿された暗号文です。


この回答が不自然に思われる場合は、お詫び申し上げます。確かにそうです。投稿者が一部の暗号文のみを提供し、その暗号文がどのように生成されたのかについての洞察を求めるこのような質問は、security.stackexchange.comで頻繁に出されるようです。そしてこの質問はしばしばそれらの複製として参照されます。 この回答のポイントは、この種の質問には無限の解があるため、この種の質問には答えられないことを示すことです。

1
mti2935

唯一の方法は、通知するメタデータがある場合です。たとえば、私は最近PDFを扱っており、その形式にはフィルター、アルゴリズム、キーサイズなどを含む辞書が含まれています。データ。

1
user185