C#でArgon2id
を使用する方法についての記事を読みましたここ。
以下は、彼らが書いたコードです(わずかに編集されています)。
__コード__
次の質問があります。
argon2id.GetBytes(16)
、より長い値を返すargon2.GetBytes(128)
を使用しています。構成が同じであると仮定すると、using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Konscious.Security.Cryptography;
namespace Playground
{
class Program
{
// No. of CPU Cores x 2.
private const int DEGREE_OF_PARALLELISM = 16;
// Recommended minimum value.
private const int NUMBER_OF_ITERATIONS = 4;
// 600 MB.
private const int MEMORY_TO_USE_IN_KB = 600000;
static void Main(string[] args)
{
var password = "SomeSecurePassword";
byte[] salt = CreateSalt();
byte[] hash = HashPassword(password, salt);
var otherPassword = "SomeSecurePassword";
var success = VerifyHash(otherPassword, salt, hash);
Console.WriteLine(success ? "Passwords match!" : "Passwords do not match.");
}
private static byte[] CreateSalt()
{
var buffer = new byte[16];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(buffer);
return buffer;
}
private static byte[] HashPassword(string password, byte[] salt)
{
var argon2id = new Argon2id(Encoding.UTF8.GetBytes(password));
argon2id.Salt = salt;
argon2id.DegreeOfParallelism = DEGREE_OF_PARALLELISM;
argon2id.Iterations = NUMBER_OF_ITERATIONS;
argon2id.MemorySize = MEMORY_TO_USE_IN_KB;
return argon2id.GetBytes(16);
}
private static bool VerifyHash(string password, byte[] salt, byte[] hash)
{
var newHash = HashPassword(password, salt);
return hash.SequenceEqual(newHash);
}
}
}
のアプローチは、128
よりも長いので、16
よりも安全ですか?
Argon2id
が使用できるメモリが多いほど、カスタマイズされたハードウェア攻撃に対してより安全になります。したがって、40
を使用した70 MB
の反復と4
を使用した600 MB
の反復にほぼ同じ時間がかかる場合でも、後者の構成の方がメモリコストが大きいため、安全性が高いと考えられます。これは正しいです?
Argon2仕様 、特にセクション9 推奨パラメーターに従って、使用するパラメーターを決定するには、次の手順を実行する必要があります。
Argon2の実用的なタイプとパラメータを選択するには、次の手順をお勧めします。
- タイプyを選択します。それらの違いがわからない場合、またはサイドチャネル攻撃を実行可能な脅威と見なす場合は、Argon2iを選択してください。それ以外の場合は、オプションのタイプを含め、どの選択でもかまいません。
- Argon2への各呼び出しによって開始できるスレッドの最大数hを計算します。
- 各呼び出しが提供できるメモリの最大量mを計算します。
- 各呼び出しが許容できる最大時間xの時間(秒単位)を計算します。
- ソルトの長さを選択します。すべてのアプリケーションで128ビットで十分ですが、スペースの制約がある場合は64ビットに減らすことができます。
- タグの長さを選択します。鍵の導出を含むほとんどのアプリケーションでは、128ビットで十分です。より長いキーが必要な場合は、より長いタグを選択してください。
- サイドチャネル攻撃が実行可能な脅威である場合は、ライブラリ呼び出しでメモリ消去オプションを有効にします。
- 異なるパス数tを使用して、タイプy、メモリmおよびhレーンおよびスレッドのスキームを実行します。実行時間がxを超えないように、最大のtを計算します。 t 1] ==であってもxを超える場合は、それに応じてmを減らします。
- 決定されたばかりの値m、h、およびtを使用してすべてのパスワードをハッシュします。
この場合の「タグ」は、Argon2の出力を指します。したがって、ドキュメントが強調しているように、128ビット(または16バイト)でほとんどのアプリケーションに十分です。より長い出力を生成しても、セキュリティは向上しません。アプリケーションで他の目的のために出力を長くする必要がある場合は、より長い出力を生成する必要があります(たとえば、AES-256のキーとして使用する256ビットの出力を生成します)。
反復回数と比較したメモリコストについては、 同様の質問 と尋ねました。その質問への回答と仕様は、環境に応じて可能な最大メモリ量を推奨しています。 この質問 とそれに対応する回答は、そのメモリに対して少なくとも3回の反復がある限り、メモリ使用量を最大化することが理にかなっている理由を説明しています。あなたのコードでは、NUMBER_OF_ITERATIONS
は、推奨最小値として4に設定されています。これは、最小値として安全と思われます。
補足として、実際に値をベンチマークする必要があります。主に重要なのは、1つのArgon2タグの計算を実行するのにかかる時間です。上記で追加された仕様と、私がリンクした質問は、このプロセスを詳しく説明しています。