私の最終的な目標は、一意で推測/予測できないURLを作成することです。このURLの目的は、ユーザーがメールアドレスの確認やパスワードのリセットなどの操作を実行できるようにすることです。これらのURLは、設定された時間(現在は24時間に設定されています)内に期限切れになります。
私はもともとGuid
この目的でを使用していましたが、聞いている専門家によっては、これが「問題ない」と「非常に安全でない」の間のどこかにあることがわかりました。ですから、念のため、コードを少し強化したいと思いました。最初は、を使用することに固執すると思いましたが、ファクトリメソッドGuid
ではなくランダムバイトから生成します。Guid.NewGuid()
これが私が思いついた方法です:
public static Guid GetRandomGuid()
{
var bytes = new byte[16];
var generator = new RNGCryptoServiceProvider();
generator.GetBytes(bytes);
return new Guid(bytes);
}
new Guid(bytes)
の代わりにを使用するとどうなるかはよくわかりませんが、この方法ではランダムなバイト配列を生成してデータ構造に格納Guid.NewGuid()
するだけだと思います。つまり、一意であることが保証されるのではなく、ランダムであることが保証されるだけです。Guid
私のURLは一意でランダムである必要があるため、これは確実な解決策のようには思えません。私は今考えています。URLは、一意のID(Guid
または、使用可能な場合はデータベースの自動インクリメントID)とから生成されたランダムシーケンスの両方の組み合わせに基づいて作成する必要がありますRNGCryptoServiceProvider
。
質問
一意であることが保証され、予測/推測が非常に困難/不可能である検証/パスワードリセットURLを生成するための最良の方法は何ですか?
一意の文字列をランダムな文字列と連結してURLを作成するだけでよいですか?
.NET Frameworkには、URLに使用できる一意のランダムな(予測できない)シーケンスを簡単に生成する方法が組み込まれていますか?
そうでない場合、利用可能なオープンソースの良いソリューションはありますか?
アップデート
誰かが同様の要件を持っている場合、私は現在次の方法を使用しています:
public static string GenerateUniqueRandomToken(int uniqueId)
// generates a unique, random, and alphanumeric token
{
const string availableChars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
using (var generator = new RNGCryptoServiceProvider())
{
var bytes = new byte[16];
generator.GetBytes(bytes);
var chars = bytes
.Select(b => availableChars[b % availableChars.Length]);
var token = new string(chars.ToArray());
return uniqueId + token;
}
}
これで問題が発生した場合はコメントしてください。