こんにちは。 約2年前、Habrahabrで私はいくつかの解説から、パスワードを保存せずに保存する興味深い方法を知りました。 このフレーズは奇妙に見えますが、このプログラムの性質をより正確に説明することはできませんでした。 この方法は、特定のサイトの特定のアカウントのパスワードを取得するために、マスターパスワード、サイトアドレスから「接着」された文字列を駆動し、サイトのログインをハッシュ関数に入力する必要があります。
キーワード+サイト名+ログイン
この行のkeywordは、すべてのサイトのパスワードを「保存」するために使用されるマスターパスワードです。 次はウェブサイトのアドレスで、ログインします。 この行をハッシュ関数に入力すると、文字列の出力が得られます。この文字列の全部または一部は、このサイトのこのアカウントのパスワードとして使用できます。 行の先頭にあるキーワードは、サイトのアドレスとログインがわかっている場合、パスワードを見つけることを不可能にします。 ハッシュ関数の結果は、パスワードには十分すぎるほどです。 しかし、パスワードの強度にはまだ多くのことが望まれています。 ハッシュ関数の結果は16進表記の数字のストリングであるため、このようなパスワードの各文字には16個の値のみを使用できます。
この欠陥を修正しようとしました。 次に、その方法を説明します。
プログラムの仕組み
ハッシュ関数の結果は16進文字列で、16進文字「0123456789ABCDEF」で構成されます。
たとえば、ハッシュ関数sha256を実行した後の「キーワード+サイト名+ログイン」の行から、ハッシュが取得されます。
dc6463dfd7d86d06db49ea63061c9a8bf6a7ff17fe23b5bd3dfbd7a25d1b6769
各文字は半バイト(ノートブック)です。 2つの隣接する文字の組み合わせは、バイトのシンボリック表現であるため、256個の値を取ることができます。 プログラムは、2文字のグループでハッシュ文字列を処理します。
dc 64 63 df d7 d8 6d 06 db 49 ea 63 06 1c 9a 8b f6 a7 ff 17 fe 23 b5 bd 3d fb d7 a2 5d 1b 67 69
プログラムは各グループを数値表現に変換します。 結果は0〜255の数値です。1つのパスワード文字をエンコードするのに十分な値を超えています。 パスワードを生成するためのプログラムでは、小文字と大文字のラテン文字と数字を使用し、合計63文字を使用できました。 次に、可能なパスワード文字のセットをアルファベットと呼びます。 複雑なパスワードが必要か、単純なパスワードが必要かによって、アルファベットを自由に作成できます。 これを行うには、プログラムの1行を変更するだけです。 プログラムはC ++で書かれています。
const string alphabet="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
次に、プログラムは、バイトをアルファベットの文字数で割った残りを見つけます(63)。 63で割った余りは、0〜62の値を取ることができます。この余りは、文字列アルファベットの文字のインデックスになります。
ハッシュの処理を担当するプログラムの一部を投稿します。 記事の最後に、プログラムの完全なソースコードへのリンクがあります。
#include <cstdio> #include <cstddef> #include <string> #include <iostream> #include "sha256.h" void convert(string strIn, string &strOut) { const string alphabet="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"; const string hex="0123456789abcdef"; unsigned char str[32]; for(int i=0; i< 32; i++) { str[i]=hex.find_first_of(strIn.at(i*2))*16+hex.find_first_of(strIn.at(i*2+1)); strOut.at(i)=alphabet.at(str[i] % alphabet.length()); } } int main() { SHA256* yourInstanceName = new SHA256(); std::string digest; string strIn, strOut="00000000000000000000000000000000"; while(true) { cin >> strIn; convert(yourInstanceName->hash(strIn), strOut); cout << strOut << endl<< endl; } return 0; }
プログラムの使用方法
プログラムの使用は簡単です。 マスターパスワード、ウェブサイトアドレス、ログインを入力してください。 Enterキーを押します。 すべての必要な情報(ウェブサイトアドレス、ログイン)は、ヘッドに保存するか、どこかに書き留めることができます。 この情報は秘密ではありません。 ただし、マスターパスワードは覚えておく必要があります。
たとえば、コンソールに次の行を入力します。
キーワード+サイト名+ログイン
Enterキーを押して、パスワードを取得します。
nEWWzxS7bwDW7lxyNI8f7mC4M4zEckYI
パスワードは32文字で構成され、非常に強力に見えます
プログラムの利点
- KeePassに類似したプログラムの場合のように、パスワードデータベースがありません。 そのため、パスワードデータベースをバックアップする必要はありません。
- パスワードデータベースは存在しないため、盗まれたりハッキングされたりすることはできません。
- プログラムの実装は非常に簡単です。
- クロスプラットフォーム、として 標準のC ++ライブラリのみが使用されます。
プログラムの短所
- この段階では、プログラムはコンソールであり、そこからパスワードをコピーすることは困難です。
- ウェブサイトのアドレスを覚えておくか、書き留めてログインする必要があります。
- パスワードの変更には問題があります。
次に、バイトをアルファベットの72文字の1つに変えるこの方法の小さなマイナスについて説明します。 マイナス面は、アルファベットの文字のインデックスとして除算の残りを使用する場合、0〜255%63のインデックスを持つアルファベットの一部がパスワードに入る可能性が高いことです。 わかりやすくするために、「おもちゃ」の3ビット数を3で除算する例を示します。3ビット数は0〜7の値を取ることができます。除算の残りを見つける操作でパーセンテージを指定しました。 高等数学はありません、ごめんなさい。
0%3 = 0 | 3%3 = 0 | 6%3 = 0 |
1%3 = 1 | 4%3 = 1 | 7%3 = 1 |
2%3 = 2 | 5%3 = 2 |
除算の残りを見つけた結果としてのデュースは、ゼロと1よりも少ない頻度で発生することがわかります。 同様の状況は、バイトをアルファベットの文字数で除算することです。 この問題は、バイトではなくワード(つまり2バイト)の残りの部分を使用することで解決できます。 そうすると、パスワードに含まれるすべての文字を取得する可能性がより高くなります。 ただし、パスワードの長さは半分に削減されます。 16文字に等しくなります。 このようなパスワードは、場合によっては短すぎると見なされます。 この問題は、ハッシュ関数を使用してハッシュを再実行することで解決できます。 このマイナスはかなり修正可能であることがわかります。
おわりに
このプログラムについてハブで話し、コメントを読みたかった。 アイデアは非常にシンプルで有望であるが、インターネット上で見つけることができなかったため、このプログラムを扱うのは興味深いものでした。 上記のようなプログラムを知っている場合は、コメントに名前を書いてください。 また、プログラムにプレゼンテーションがないという事実のために、あまりにも激しく蹴らないでください。 プログラムはトレーニングと見なされる必要があります。
アーカイブへのリンクには、コンパイルされたプログラムとソースが含まれています。すべてがGPLライセンスの下で配布されています。 =)
rusfolder.com/31528284