На моем предыдущем концерте мы сохранили пароль в виде хешированного / зашифрованного / соленого значения (в то время с использованием MD5) как VARBINARY(32)
. Чтобы позже сравнить пароль, вместо того, чтобы пытаться его расшифровать, мы сравнили бы зашифрованное + солёное значение, которое мы сохранили, с зашифрованным + солёным значением пытаемого пароля. Если они совпали, они вошли, если они не совпали, они не вошли.
Хеширование выполнялось на среднем уровне (как для первоначального сохранения пароля, так и для последующего сравнения), но на примере на основе SQL Server (чтобы остановить ворчание @Yahia, это не означает, что вы укажете наиболее безопасный способ возможно, я просто иллюстрирую методологию на очень легком примере. MD5 недостаточно силен для вас? Вы можете использовать другой, более сложный алгоритм вместе с более продвинутыми методами соления, особенно если вы выполняете хеширование на уровне приложения strong >):
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) - это значительно усложняет «обнюхивание» фактического пароля в открытом виде из любого места. И вы, возможно, не стали бы хранить соль в виде обычного текста вместе с кодом, а получить ее из другого места.
Это определенно более безопасно, чем хранение пароля в незашифрованном виде, но при этом исключается возможность его восстановления. На мой взгляд беспроигрышный вариант.
person
Aaron Bertrand
schedule
05.09.2011