0

私の ASP.NET MVC Web アプリケーションは、ユーザーに代わっていくつかのデータを作成し、数値の主キーを持つレコードの SQL データベースに格納します。主キーを介してデータにアクセスします。

認証されたユーザーが (数値の) プライマリ キーを含む URL に移動できるようにしたいのですが、実際のキーの値を公開したくありません。したがって、コードに焼き付けられた文字列とログインしているユーザーの UserID で構成されるパスワードを使用して、数値キーを (対称暗号化アルゴリズムを使用して) 暗号化したいようです。結果の URL は次のようになります: https://foo.com/123abc、ここで、「123abc」は暗号化されたキー値 (バイトから文字に変換) です。理論的には (初心者の脳にとって) この暗号化された値は、たとえ悪意のある第三者によって取得されたとしても、その当事者がユーザーの資格情報を使用して私の Web サイトにログインできない限り、役に立ちません。

質問 1:これはこの種のことを行う正しい方法ですか?
質問 2:このことを知っている人が、この目的に使用できる単純な対称暗号化 API を教えてくれますか?

4

3 に答える 3

2

PK を使用する代わりに、SQL テーブルに列を追加し、その型を uniqueidentifier に設定し、その値を NEWID() に設定して、それをユーザーに表示することができます。このソリューションは、オーバーヘッドを最小限に抑えながら、後でそのユーザーに関連付けることができる一見ランダムなシリーズ。

ALTER TABLE foo ADD foobar uniqueIdentifier default newid();

http://msdn.microsoft.com/en-us/library/ms187942.aspx

于 2013-03-12T17:26:44.450 に答える
1

整数の対称暗号化は非常に簡単に解読できるので、気にしない方がよいでしょう。さて、Base64でエンコードするなどして、ソルトしたり、少し難解にしたりすることができますが、それでも、これはかなり無意味です。データベースの主キーは機密データではありません。データベースにアクセスできなければ意味がありません。データベースにアクセスできる場合は、IDで特定のユーザーを検索することで問題が発生することはほとんどありません。対称的な暗号化でさえ、単に必要のないもののためにアプリケーションにかなりのオーバーヘッドを追加します。

PKを公開したくない場合は、URLでユーザー名などを使用し、それによってユーザーを検索します。

于 2013-03-12T17:19:07.593 に答える
0

あなたはそれを行うことができます、確かに。

セッションにソルトを保存するか、毎回ランダムに生成するか、セッション ID をソルトとして使用します。

以下は、salt を使用して文字列値を暗号化/復号化できる 2 つの方法です。初期ベクトルの代わりにソルトを使用できます。

public static string Encrypt(string PlainText, string Password, string Salt,
 string HashAlgorithm = "SHA1", int PasswordIterations = 16, string InitialVector = "Initial Vector", int KeySize = 256)
{  
    byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
    byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
    byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);
    PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
    byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
    RijndaelManaged SymmetricKey = new RijndaelManaged();
    SymmetricKey.Mode = CipherMode.CBC;

    ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);

    MemoryStream MemStream = new MemoryStream();
    CryptoStream cryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
    cryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
    cryptoStream.FlushFinalBlock();
    byte[] CipherTextBytes = MemStream.ToArray();

    MemStream.Close();
    cryptoStream.Close();
    Encryptor.Dispose();
    Encryptor = null;

    return Convert.ToBase64String(CipherTextBytes);
}


public static string Decrypt(string CipherText, string Password, string Salt,
    string HashAlgorithm = "SHA1", int PasswordIterations = 16, string InitialVector = "Initial Vector", int KeySize = 256)
{ 
    byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
    byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
    byte[] CipherTextBytes = Convert.FromBase64String(CipherText);
    PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
    byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
    RijndaelManaged SymmetricKey = new RijndaelManaged();
    SymmetricKey.Mode = CipherMode.CBC;

    ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes);
    MemoryStream MemStream = new MemoryStream(CipherTextBytes);
    CryptoStream cryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read);
    byte[] PlainTextBytes = new byte[CipherTextBytes.Length];

    int ByteCount = cryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length);

    MemStream.Close();
    cryptoStream.Close();
    Decryptor.Dispose();
    Decryptor = null;

    return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount);
}
于 2013-03-12T17:16:08.453 に答える