私の以前のギグでは、パスワードをハッシュ/暗号化/ソルト値 (当時は MD5 を使用) としてVARBINARY(32)
. 後でパスワードを比較するには、パスワードを復号化するのではなく、保存した暗号化された + ソルト化された値と、試行されたパスワードの暗号化された + ソルト化された値を比較します。合っていれば入り、合わなかったら入りませんでした。
ハッシュ作業は中間層で行われました (最初にパスワードを保存するためと、後で比較するための両方) が、SQL Server ベースの例 ( @Yahia の不平を言うのを止めるため、これは可能な限り最も安全な方法を伝えることを意図したものではありません。非常に軽量な例で方法論を説明しているだけです.MD5はあなたにとって十分に強力ではありませんか?アプリケーション層でハッシュを実行する場合は特に、より高度なソルティング技術とともに、別のより複雑なアルゴリズムを使用できます):
CREATE TABLE dbo.Users
(
UserID INT IDENTITY(1,1) PRIMARY KEY,
Username NVARCHAR(255) NOT NULL UNIQUE,
PasswordHash VARBINARY(32) NOT NULL
);
ユーザーを作成する手順 (エラー処理や重複防止はなく、疑似のみ)。
CREATE PROCEDURE dbo.User_Create
@Username NVARCHAR(255),
@Password NVARCHAR(16)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @salt NVARCHAR(16) = '$w0rdf1$h';
INSERT dbo.Users(Username, Password)
SELECT @Username,
CONVERT(VARBINARY(32), HASHBYTES('MD5', @Password + @Salt));
END
GO
次に、ユーザーを認証する手順です。
CREATE PROCEDURE dbo.User_Authenticate
@Username NVARCHAR(255),
@Password NVARCHAR(16)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @salt NVARCHAR(16) = '$w0rdf1$h';
IF EXISTS
(
SELECT 1 FROM dbo.Users
WHERE Username = @Username AND
PasswordHash = CONVERT(VARBINARY(32), HASHBYTES('MD5', @Password + @salt))
)
BEGIN
PRINT 'Please, come on in!';
END
ELSE
BEGIN
PRINT 'You can keep knocking but you cannot come in.';
END
END
GO
実際には、アプリケーション内でハッシュを実行し、ハッシュ値を VARBINARY(32) として渡す可能性があります。これにより、実際の平文パスワードをどこからでも「盗聴」することがはるかに難しくなります。また、ソルトをコードと一緒にプレーンテキストで保存するのではなく、他の場所から取得することもできます。
これは、パスワードを暗号化せずに保存するよりも確実に安全ですが、パスワードを取得する機能がなくなります。私の意見では、ウィンウィンです。