MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtの基礎 - ハッシュ値のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtの基礎 - ハッシュ値
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == ハッシュとは、任意のサイズのデータを固定長のデータに変換するアルゴリズムである。<br> ハッシュ関数と呼ばれる特殊な関数を使用して、入力データからハッシュ値 (ダイジェストとも呼ばれる) を生成する。<br> <br> ハッシュの特徴を以下に示す。<br> * 一方向性 *: ハッシュ値から元のデータを復元することは計算上非常に困難である。 * 固定長出力 *: 入力データのサイズに関係なく、ハッシュ値は常に固定長になる。 * 一意性 *: 異なる入力データから同じハッシュ値が生成される可能性は非常に低い。 (衝突耐性) * 高速性 *: ハッシュ関数は効率的で、大量のデータを高速に処理できる。 <br> ハッシュの用途を以下に示す。<br> * データの整合性検証 *: ハッシュ値を比較することで、データが改ざんされていないことを確認できる。 * パスワードの保存 *: パスワードをそのまま保存するのではなく、ハッシュ値を保存することでセキュリティを向上させる。 * データの識別 *: ハッシュ値を使用してデータを一意に識別できる。 * 署名生成 *: デジタル署名においてハッシュ関数が使用される。 <br> 代表的なハッシュアルゴリズムを以下に示す。<br> * MD5 *: 古くから使用されてきたが、現在は脆弱性が発見されている。 * SHA-1 *: MD5の後継として広く使用されてきたが、現在は衝突耐性に問題があることが判明している。 * SHA-2 (SHA-256, SHA-384, SHA-512) *: 現在広く使用されている安全なハッシュアルゴリズムである。 *: <br> *: SHA-2は現在のコンピューティング能力では十分に安全であり、多くのシステムやプロトコルで広く使用されている。 *: SHA-3への移行には、ソフトウェアやインフラストラクチャの更新が必要であり、コストと時間が掛かるため、緊急性がない限り、急激な変更は推奨されない。 * SHA-3 *: SHA-2の後継として設計された新しいハッシュアルゴリズムである。 *: <br> *: ただし、新しいシステムを設計する際や、長期的なセキュリティを考慮する必要がある場合には、SHA-3の採用を検討することを推奨する。 *: SHA-3は、量子コンピュータによる攻撃に対してより耐性があると考えられており、将来を見据えた選択肢となっている。 <br> ハッシュは、データの完全性検証、パスワードの保護、効率的なデータ検索等、ソフトウェア開発のさまざまな場面で活用されてる。<br> 適切なハッシュアルゴリズムを選択し、ハッシュの特性を理解することが重要である。<br> <br><br> == QCryptographicHashクラス == ==== ハッシュ化 ==== MD5、SHA-2、SHA-3等のハッシュを求める場合、<code>QCryptographicHash</code>クラスの<code>hash</code>メソッドを使用する。<br> <br> 以下の例では、任意の文字列から、MD4、MD5、SHA-2、SHA-3のハッシュを計算している。<br> <br> サポートされているハッシュの詳細については、[http://doc.qt.io/qt-5/qcryptographichash.html#Algorithm-enum Qtの公式ドキュメント]を参照すること。<br> <syntaxhighlight lang="c++"> #include <QCoreApplication> #include <QCryptographicHash> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // ハッシュ化する文字列 QString input = "Hello, world!"; // MD4 QByteArray md4Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Md4); QString md4HexHash = md4Hash.toHex(); qDebug() << "MD4 Hash:" << md4HexHash; // MD5 QByteArray md5Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Md5); QString md5HexHash = md5Hash.toHex(); qDebug() << "MD5 Hash:" << md5HexHash; // SHA-2 (SHA-224) QByteArray sha224Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha224); QString sha224HexHash = sha224Hash.toHex(); qDebug() << "SHA-2 (SHA-224) Hash:" << sha224HexHash; // SHA-2 (SHA-256) QByteArray sha256Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha256); QString sha256HexHash = sha256Hash.toHex(); qDebug() << "SHA-2 (SHA-256) Hash:" << sha256HexHash; // SHA-2 (SHA-384) QByteArray sha384Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha384); QString sha384HexHash = sha384Hash.toHex(); qDebug() << "SHA-2 (SHA-384) Hash:" << sha384HexHash; // SHA-2 (SHA-512) QByteArray sha512Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha512); QString sha512HexHash = sha512Hash.toHex(); qDebug() << "SHA-2 (SHA-512) Hash:" << sha512HexHash; // SHA-3 (SHA3-224) QByteArray sha3_224Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha3_224); QString sha3_224HexHash = sha3_224Hash.toHex(); qDebug() << "SHA-3 (SHA3-224) Hash:" << sha3_224HexHash; // SHA-3 (SHA3-256) QByteArray sha3_256Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha3_256); QString sha3_256HexHash = sha3_256Hash.toHex(); qDebug() << "SHA-3 (SHA3-256) Hash:" << sha3_256HexHash; // SHA-3 (SHA3-384) QByteArray sha3_384Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha3_384); QString sha3_384HexHash = sha3_384Hash.toHex(); qDebug() << "SHA-3 (SHA3-384) Hash:" << sha3_384HexHash; // SHA-3 (SHA3-512) QByteArray sha3_512Hash = QCryptographicHash::hash(input.toUtf8(), QCryptographicHash::Sha3_512); QString sha3_512HexHash = sha3_512Hash.toHex(); qDebug() << "SHA-3 (SHA3-512) Hash:" << sha3_512HexHash; return a.exec(); } </syntaxhighlight> <br> ==== セキュリティ対策を施したハッシュ化の例 ==== <code>QCryptographicHash</code>クラスは、暗号学的ハッシュ関数を提供するためのクラスであるが、<br> ソルト値の追加やPBKDF2等の鍵引き伸ばし関数の適用は自動的には行わない。<br> <br> そのため、これらの機能を使用する場合は、設計者側で実装する必要がある。<br> <br> パスワードのハッシュ化を安全に行う場合は、以下に示すような手順を実装することが推奨される。<br> * ソルト値の生成 *: パスワード毎にランダムな一意のソルト値を生成する。 *: ソルト値は、十分に長く、暗号学的に安全な乱数生成器を使用して生成する必要がある。 * パスワードとソルト値の結合 *: ソルト値をパスワードに結合する。 *: 一般的には、パスワードの前後にソルト値を付加する。 * 鍵引き伸ばし関数の適用 *: 結合したパスワードとソルト値に対して、PBKDF2等の鍵引き伸ばし関数を適用する。 *: 鍵引き伸ばし関数は、計算コストを調整できるパラメータを持ち、ハッシュ計算に時間が掛かるようにすることで、ブルートフォース攻撃を困難にする。 * ハッシュ値の生成 *: 鍵引き伸ばし関数により得られた結果を、暗号学的ハッシュ関数(SHA-256等)で処理して、最終的なハッシュ値を生成する。 * ハッシュ値とソルト値の保存 *: 生成されたハッシュ値とソルト値をデータベース等に安全に保存する。 <br> QtではPBKDF2を直接サポートするクラスは無いが、<code>QMessageAuthenticationCode</code>クラスと<code>QCryptographicHash</code>クラスを組み合わせることにより、PBKDF2を実装することができる。<br> <br> 以下の例は、PBKDF2-HMAC-SHA256を使用したパスワードをハッシュ化している。<br> <br> まず、<code>QRandomGenerator</code>クラスを使用してランダムなソルト値を生成し、次に、パスワードとソルト値を結合してPBKDF2-HMAC-SHA256を適用している。<br> また、反復回数とキーの長さを指定することにより、計算コストを調整することができる。<br> ただし、実際の設計では、イテレーション回数を適切に調整して、ハードウェアの進歩に合わせて定期的に更新する必要がある。<br> <syntaxhighlight lang="c++"> #include <QCryptographicHash> #include <QMessageAuthenticationCode> #include <QRandomGenerator> QByteArray hashPassword(const QString &password, const QByteArray &salt, int iterations, int keyLength) { QMessageAuthenticationCode hmac(QCryptographicHash::Sha256); QByteArray derivedKey(keyLength, Qt::Uninitialized); hmac.setKey(password.toUtf8() + salt); QByteArray U = hmac.result(); QByteArray T = U; for (int i = 1; i < iterations; ++i) { hmac.addData(U); U = hmac.result(); T = T.toHex().append(U.toHex()); } return QCryptographicHash::hash(T, QCryptographicHash::Sha256).left(keyLength); } int main(int argc, char *argv[]) { // ...略 QString password = "myPassword"; QByteArray salt = QRandomGenerator::global()->generate(16).toHex(); int iterations = 10000; int keyLength = 32; QByteArray hashedPassword = hashPassword(password, salt, iterations, keyLength); // ...略 } </syntaxhighlight> <br> ただし、セキュリティ上重要な用途では、専門家によって監査・検証されたライブラリや実装を使用することが推奨される。<br> <br><br> == QMessageAuthenticationCodeクラス == ==== ハッシュ化 ==== 以下の例では、<code>QMessageAuthenticationCode</code>クラスを使用して、MD4、MD5、SHA-2、SHA-3でハッシュ化している。<br> <br> 各ハッシュアルゴリズムに対して、<code>QMessageAuthenticationCode</code>オブジェクトを作成して、コンストラクタでアルゴリズムを指定する。<br> <code>addData</code>メソッドを使用して、ハッシュ化する文字列をUTF-8エンコードで追加する。<br> <code>result</code>メソッドを使用してハッシュ値を取得し、<code>toHex</code>メソッドで16進数表記の文字列に変換する。<br> <br> 出力結果は、<code>QCryptographicHash</code>クラスを使用した場合と同値となる。<br> <br> <code>QMessageAuthenticationCode</code>クラスは、主にメッセージ認証コード (MAC) の計算に使用されるが、このようにハッシュ化にも使用することができる。<br> <u>ただし、一般的なハッシュ化の用途では、<code>QCryptographicHash</code>クラスを使用する方が簡潔で便利である。</u><br> <syntaxhighlight lang="c++"> #include <QCoreApplication> #include <QMessageAuthenticationCode> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // ハッシュ化する文字列 QString input = "Hello, world!"; // MD4 QMessageAuthenticationCode md4(QCryptographicHash::Md4); md4.addData(input.toUtf8()); QByteArray md4Hash = md4.result().toHex(); qDebug() << "MD4 Hash:" << md4Hash; // MD5 QMessageAuthenticationCode md5(QCryptographicHash::Md5); md5.addData(input.toUtf8()); QByteArray md5Hash = md5.result().toHex(); qDebug() << "MD5 Hash:" << md5Hash; // SHA-2 (SHA-224) QMessageAuthenticationCode sha224(QCryptographicHash::Sha224); sha224.addData(input.toUtf8()); QByteArray sha224Hash = sha224.result().toHex(); qDebug() << "SHA-2 (SHA-224) Hash:" << sha224Hash; // SHA-2 (SHA-256) QMessageAuthenticationCode sha256(QCryptographicHash::Sha256); sha256.addData(input.toUtf8()); QByteArray sha256Hash = sha256.result().toHex(); qDebug() << "SHA-2 (SHA-256) Hash:" << sha256Hash; // SHA-2 (SHA-384) QMessageAuthenticationCode sha384(QCryptographicHash::Sha384); sha384.addData(input.toUtf8()); QByteArray sha384Hash = sha384.result().toHex(); qDebug() << "SHA-2 (SHA-384) Hash:" << sha384Hash; // SHA-2 (SHA-512) QMessageAuthenticationCode sha512(QCryptographicHash::Sha512); sha512.addData(input.toUtf8()); QByteArray sha512Hash = sha512.result().toHex(); qDebug() << "SHA-2 (SHA-512) Hash:" << sha512Hash; // SHA-3 (SHA3-224) QMessageAuthenticationCode sha3_224(QCryptographicHash::Sha3_224); sha3_224.addData(input.toUtf8()); QByteArray sha3_224Hash = sha3_224.result().toHex(); qDebug() << "SHA-3 (SHA3-224) Hash:" << sha3_224Hash; // SHA-3 (SHA3-256) QMessageAuthenticationCode sha3_256(QCryptographicHash::Sha3_256); sha3_256.addData(input.toUtf8()); QByteArray sha3_256Hash = sha3_256.result().toHex(); qDebug() << "SHA-3 (SHA3-256) Hash:" << sha3_256Hash; // SHA-3 (SHA3-384) QMessageAuthenticationCode sha3_384(QCryptographicHash::Sha3_384); sha3_384.addData(input.toUtf8()); QByteArray sha3_384Hash = sha3_384.result().toHex(); qDebug() << "SHA-3 (SHA3-384) Hash:" << sha3_384Hash; // SHA-3 (SHA3-512) QMessageAuthenticationCode sha3_512(QCryptographicHash::Sha3_512); sha3_512.addData(input.toUtf8()); QByteArray sha3_512Hash = sha3_512.result().toHex(); qDebug() << "SHA-3 (SHA3-512) Hash:" << sha3_512Hash; return a.exec(); } </syntaxhighlight> <br> ==== セキュリティ対策を施したハッシュ化の例 ==== ソルト値はレインボーテーブル攻撃を防ぐために使用され、PBKDF2はブルートフォース攻撃を困難にするために、意図的に計算コストを高くする。<br> <br> ただし、実際の設計では、ソルト値とハッシュ値を安全に保存する必要がある。<br> また、反復回数やキーの長さ等のパラメータは、セキュリティ要件に応じて適切に調整する必要がある。<br> <br> セキュリティ上重要な用途では、専門家によって監査・検証されたライブラリや実装を使用することを強く推奨する。<br> <br> 以下の例では、ソルト値を使用して、PBKDF2アルゴリズムを適用してパスワードをハッシュ化している。<br> # QRandomGenerator::global()->generate(16)を使用して、16バイトのランダムなソルト値を生成する。 # pbkdf2関数において、QMessageAuthenticationCodeクラスを使用してPBKDF2アルゴリズムを実装する。 #* パスワードとソルト値を連結してHMAC(SHA-256)のキーとして設定する。 #* 指定された反復回数(iterations)だけHMACを繰り返し適用します。 #* 各反復で得られたハッシュ値をXORして、最終的な派生キーを生成します。 # pbkdf2関数の引数として、パスワード、ソルト値、反復回数、キーの長さを指定する。 # 生成されたハッシュ値 (派生キー) を16進数表記の文字列に変換して出力する。 <syntaxhighlight lang="c++"> #include <QCoreApplication> #include <QMessageAuthenticationCode> #include <QRandomGenerator> #include <QDebug> QByteArray pbkdf2(const QString &password, const QByteArray &salt, int iterations, int keyLength) { QMessageAuthenticationCode hmac(QCryptographicHash::Sha256); QByteArray derivedKey(keyLength, Qt::Uninitialized); hmac.setKey(password.toUtf8() + salt); QByteArray U = hmac.result(); QByteArray T = U; for (int i = 1; i < iterations; ++i) { hmac.addData(U); U = hmac.result(); for (int j = 0; j < keyLength; ++j) { T[j] = T[j] ^ U[j]; } } return T; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // パスワード QString password = "myPassword"; // ソルト値の生成 QByteArray salt = QRandomGenerator::global()->generate(16).toHex(); // PBKDF2パラメータ int iterations = 10000; int keyLength = 32; // PBKDF2の適用 QByteArray hashedPassword = pbkdf2(password, salt, iterations, keyLength); // 結果の出力 qDebug() << "Password:" << password; qDebug() << "Salt:" << salt; qDebug() << "Iterations:" << iterations; qDebug() << "Key Length:" << keyLength; qDebug() << "Hashed Password:" << hashedPassword.toHex(); return a.exec(); } </syntaxhighlight> <br><br> == QSslクラス == QSslクラスには、<code>hash</code>というスタティックメソッドが存在する。<br> このメソッドを使用することにより、指定されたアルゴリズムでデータのハッシュ値を計算することができる。<br> <br> サポートされているアルゴリズムは、<code>QCryptographicHash</code>クラスと同様である。<br> <br> ==== ハッシュ化 ==== 以下の例では、<code>QSsl::hash</code>メソッドを使用して、任意の文字列をMD4、MD5、SHA-2、SHA-3でハッシュ化している。<br> <br> <code>QSsl::hash</code>メソッドにおいて、第1引数にハッシュ化する文字列をUTF-8エンコードで渡して、第2引数に使用するハッシュアルゴリズムを指定する。<br> 戻り値は、計算されたハッシュ値が<code>QByteArray</code>型である。<br> <br> また、<code>toHex</code>メソッドを使用して、ハッシュ値を16進数表記の文字列に変換している。<br> <br> <u>出力は、<code>QCryptographicHash</code>クラスや<code>QMessageAuthenticationCode</code>クラスを使用した場合と同値になる。</u><br> <br> <code>QSsl::hash</code>メソッドは、<code>QCryptographicHash</code>クラスと同様のインターフェースを提供しているが、<code>QSsl</code>クラスの一部として提供されている。<br> <code>QSsl</code>クラスは、SSL/TLSの暗号化や認証に関連する機能を提供するクラスであるが、一般的なハッシュ化の用途では、<code>QCryptographicHash</code>クラスを使用するのが一般的である。<br> <syntaxhighlight lang="c++"> #include <QCoreApplication> #include <QSslSocket> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // ハッシュ化する文字列 QString input = "Hello, world!"; // MD4 QByteArray md4Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Md4).toHex(); qDebug() << "MD4 Hash:" << md4Hash; // MD5 QByteArray md5Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Md5).toHex(); qDebug() << "MD5 Hash:" << md5Hash; // SHA-2 (SHA-224) QByteArray sha224Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha224).toHex(); qDebug() << "SHA-2 (SHA-224) Hash:" << sha224Hash; // SHA-2 (SHA-256) QByteArray sha256Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha256).toHex(); qDebug() << "SHA-2 (SHA-256) Hash:" << sha256Hash; // SHA-2 (SHA-384) QByteArray sha384Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha384).toHex(); qDebug() << "SHA-2 (SHA-384) Hash:" << sha384Hash; // SHA-2 (SHA-512) QByteArray sha512Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha512).toHex(); qDebug() << "SHA-2 (SHA-512) Hash:" << sha512Hash; // SHA-3 (SHA3-224) QByteArray sha3_224Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha3_224).toHex(); qDebug() << "SHA-3 (SHA3-224) Hash:" << sha3_224Hash; // SHA-3 (SHA3-256) QByteArray sha3_256Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha3_256).toHex(); qDebug() << "SHA-3 (SHA3-256) Hash:" << sha3_256Hash; // SHA-3 (SHA3-384) QByteArray sha3_384Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha3_384).toHex(); qDebug() << "SHA-3 (SHA3-384) Hash:" << sha3_384Hash; // SHA-3 (SHA3-512) QByteArray sha3_512Hash = QSsl::hash(input.toUtf8(), QCryptographicHash::Sha3_512).toHex(); qDebug() << "SHA-3 (SHA3-512) Hash:" << sha3_512Hash; return a.exec(); } </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
Qtの基礎 - ハッシュ値
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse