すべて正しいので、ここですべての回答に賛成票を投じました(私の前にここにあるものも!)。
ただし、あなたが犯している大きな間違いがあります(私も早い段階で犯したものです)-IVまたはキーをシードするために文字列を使用しないでください!!!
コンパイル時の文字列リテラルは Unicode 文字列であり、バイト値のランダムまたは十分な広がりを取得しないという事実にもかかわらず (ランダムな文字列でさえ、バイト範囲が狭いために多くの繰り返しバイトが含まれるため)印刷可能な文字)、実際には 1 バイトではなく 2 バイトを必要とする文字を取得するのは非常に簡単です。キーボードでよりエキゾチックな文字を 8 つ使ってみると、私の言いたいことがわかります。バイトに変換すると、 8バイト以上。
わかりました-ASCIIエンコーディングを使用しています-しかし、それは非ランダムな問題を解決しません。
代わりに、RNGCryptoServiceProvider を使用して IV とキーを初期化する必要があります。将来の使用のために定数値を取得する必要がある場合は、引き続きそのクラスを使用する必要がありますが、結果は16 進文字列または Base-64 でエンコードされた値 (ただし、16進数の方が好きです)。
これを簡単に実現するために、.Net PRNG を使用して 16 進文字列を生成するVS で使用するマクロ (キーボード ショートカットCTRL+SHIFT+G、CTRL+SHIFT+Hにバインド) を作成しました。
Public Sub GenerateHexKey()
Dim result As String = InputBox("How many bits?", "Key Generator", 128)
Dim len As Int32 = 128
If String.IsNullOrEmpty(result) Then Return
If System.Int32.TryParse(result, len) = False Then
Return
End If
Dim oldCursor As Cursor = Cursor.Current
Cursor.Current = Cursors.WaitCursor
Dim buff((len / 8) - 1) As Byte
Dim rng As New System.Security.Cryptography.RNGCryptoServiceProvider()
rng.GetBytes(buff)
Dim sb As New StringBuilder(CType((len / 8) * 2, Integer))
For Each b In buff
sb.AppendFormat("{0:X2}", b)
Next
Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
Dim editPoint As EnvDTE.EditPoint
selection.Insert(sb.ToString())
Cursor.Current = oldCursor
End Sub
あとは、16 進文字列リテラルをバイト配列に変換するだけです。便利な拡張メソッドを使用してこれを行います。
public static byte[] FromHexString(this string str)
{
//null check a good idea
int NumberChars = str.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(str.Substring(i, 2), 16);
return bytes;
}
おそらくそれを行うにはもっと良い方法がありますが、私にとってはうまくいきます。