たくさんの「色」を含む配列があり、この色の順序を(ランダムに)変更したいのですが、パスワードを使用します。別のユーザーが配列の「元の」(そして正しい)シーケンスを取得できるのは、正しいパスワード。Visual Basic .NETまたはC#でこれを行うにはどうすればよいですか?特定の暗号化エンジンを使用する必要がありますか?
2 に答える
これは、パスワードを使用して色の配列をスクランブルする簡単な方法です。
重要なのは、パスワードを文字列から数字に変換することです。次に、その番号を乱数ジェネレーターのシードとして使用できます。その後、その乱数ジェネレーターを使用して、カラー配列と同じ長さの順列を取得できます。その順列を使用して、色の順序を変更し、配列をスクランブルすることができます。
復号化するときに、同じパスワードが与えられている場合は、同じ順列を生成し、配列を元の形式にスクランブル解除できます。
これは、C#で記述されたその原則の例です。
int[] GetPermutation(int size, int seed)
{
Random random = new Random(seed);
int[] array = new int[size];
for (int i = 0; i < size; i++)
array[i] = i;
for (int i = array.Length; i > 1; i--)
{
int j = random.Next(i);
int tmp = array[j];
array[j] = array[i - 1];
array[i - 1] = tmp;
}
return array;
}
Color[] Encrypt(Color[] input, string password)
{
int seed = password.GetHashCode();
int[] perm = GetPermutation(input.Length, seed);
Color[] encrypted = new Color[input.Length];
for (int i = 0; i < input.Length; i++)
{
encrypted[perm[i]] = input[i];
}
return encrypted;
}
Color[] Decrypt(Color[] input, string password)
{
int seed = password.GetHashCode();
int[] perm = GetPermutation(input.Length, seed);
Color[] decrypted = new Color[input.Length];
for (int i = 0; i < input.Length; i++)
{
decrypted[i] = input[perm[i]];
}
return decrypted;
}
このGetPermutation
関数は、パラメーターとして渡されたシードに基づいて順列を生成します。Encrypt
and関数はDecrypt
、実際には配列をスクランブルおよびスクランブル解除します。
使用例は次のとおりです。
Color[] array = new Color[5] { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Black };
string password = "secret";
Color[] enc = Encrypt(array, password); // will always return Blue, Green, Black, Yellow, Red for the "secret" password
Color[] dec = Decrypt(enc, password); // will return the original array: Red, Green, Blue, Yellow, Black if given the "secret" password
Color[] dec2 = Decrypt(enc, "incorrectpwd"); // will return Green, Blue, Yellow, Black, Red, which is incorrect because the password was incorrect
ノート:
.GetHashCode()
簡単にするためにこの方法を使用しました。このメソッドは、.NETFrameworkの将来のバージョンで同じ文字列に対して異なる数値を生成する可能性があります配列の長さが短い場合は、異なるパスワードで同じ暗号化順序を取得でき、パスワードが間違っていても復号化は成功します。例えば:
Color[] array = new Color[2] {Color.Red, Color.Green}; Color[] enc = Encrypt(array, "one"); // will return Green, Red Color[] dec = Decrypt(enc, "one"); // will return Red, Green Color[] dec2 = Decrypt(enc, "two"); // will also return Red, Green, even though the password was incorrect
パスワードの代わりに色を使用する場合は、すべてのパスワードのスペースが文字、数字、記号で構成されるパスワードほど高くないため、セキュリティが失われることに注意する必要があります。このようなパスワードを総当たり攻撃するのははるかに簡単です。
私はこれがうまくいくかもしれないと推測しています:
- ユーザーにパスワードを入力してもらう
- パスワードをハッシュし(ここではC ++のいくつかのサンプルハッシュ)、数値の結果を保存します
- ハッシュをシードとしてシャッフルアルゴリズムを使用します。たとえば、ここを参照してください
Random
。ハッシュをシードとしてオブジェクトを初期化するだけです。
繰り返しになりますが、ハッシュは(衝突する可能性があるため)常に完全であるとは限らないため、問題に適したハッシュアルゴリズムを見つける必要がある場合があります。
編集:
これがあなたを助けるかもしれないいくつかのコードです:
String input = "User inputted string here";
int hashSeed = input.GetHashCode();
Random rnd = new Random(hashSeed);
Color[] MyRandomColorArray = MyColorArray.OrderBy(x => rnd.Next()).ToArray();
注: GetHashCode()は、32ビットシステムと64ビットシステムのどちらを使用しているかに関係なく、異なる値を返します。