2011-09-05 4 views
1

J'ai une fenêtre de connexion qui obtient le nom d'utilisateur et mot de passe de l'utilisateur et je voudrais savoir la meilleure façon de gérer le mot de passe. Le nom d'utilisateur est juste une zone de texte normale, mais le mot de passe est un PasswordBox. Je passe le nom d'utilisateur directement au ViewModel, mais je ne définis une propriété SecureString sur le ViewModel qu'une fois que le bouton de connexion a été cliqué en utilisant Code-Behind. Une fois le mot de passe SecureString défini, je veux valider.Stocker, récupérer et valider le mot de passe (SecureString) dans SQL Server

Je suis en train d'écrire le LoginBox maintenant, mais je n'ai pas encore complètement élaboré le Modèle. Comment dois-je stocker le mot de passe dans SQL Server? Est-ce que j'écris simplement le contenu de SecureString à SQL et essaye alors de le comparer quand l'utilisateur essaye de se connecter?

+0

Quelque chose comme ça? http://stackoverflow.com/questions/1191112/password-hashing-salt-and-storage-of-hashed-values ​​ – CodeCaster

+0

Cela aide à hacher le mot de passe, mais dans quel type de données puis-je le stocker et comment puis-je travailler avec SecureStrings pour faire la comparaison par la suite? –

+1

Le type de données devrait probablement être un varchar, et un SecureString n'est pas une solution magique, c'est simplement une chaîne protégée des attaques, vous ne pouvez pas lire son contenu de la mémoire depuis l'extérieur de votre programme, mais c'est tout. – CodeCaster

Répondre

4

Vous ne devez JAMAIS stocker un mot de passe - même pas crypté ...

magasin juste un hachage du mot de passe (qui empêche la pasword d'être jamais récupéré tant que le hachage est mis en œuvre de manière sécurisée) et pour la validation que vous Hacher le mot de passe fourni par l'utilisateur de la même manière et de comparer les résultats ...

Il existe des normes pour le faire:

La norme ci-dessus rend difficile d'utiliser les tables arc-en-etc., car il rend le calcul très coûteux car il utilise plusieurs tours en plus d'un sel ...ainsi le hachage est par exemple 1000 fois plus lent (avec 1000 rounds) mais c'est exactement ce que vous voulez - l'attaquant devra faire le même calcul et aura donc besoin de 1000 fois la puissance ou le temps nécessaire pour atteindre le but par force brute.

Vous pouvez stocker le résultat soit directement sous VARBINARY, soit sous VARCHAR après l'encodage Base64 ou HEX des octets ... vous devrez stocker le sel avec lui (ce qui n'est pas un risque de sécurité tant que chaque mot de passe obtient son propre sel aléatoire généré cryptographiquement sécurisé distinct).

+0

Voilà ce que j'étais Je me demandais comment faire, je pense que ce que CodeCaster met dans les commentaires fonctionnera –

+0

Comment puis-je stocker le sel? Quel type de données? –

+0

le sel est juste un 'byte []' et peut être soit stocké comme VARBINARY ou comme VARCHAR après l'encodage en Base64 ou en HEX ... – Yahia

0

Lors de mon précédent concert, nous avons stocké le mot de passe en tant que valeur hachée/cryptée/salée (en utilisant MD5 à ce moment) comme VARBINARY(32). Pour comparer le mot de passe plus tard, plutôt que d'essayer de déchiffrer le mot de passe, nous comparons la valeur cryptée + salée que nous avons stockée à la valeur cryptée + salée du mot de passe en cours de tentative. S'ils correspondaient, ils entraient, s'ils ne correspondaient pas, ils n'entraient pas.

Le travail de hachage a été fait dans le niveau intermédiaire (à la fois pour enregistrer le mot de passe initialement et pour comparer plus tard), mais un Exemple basé sur SQL Server (pour arrêter les grognements de Yahia, ce n'est pas pour vous dire la manière la plus sûre possible, je suis juste illustrer la méthodologie avec un exemple très léger. MD5 pas assez fort pour vous? Vous pouvez utiliser un autre et un algorithme plus complexe ainsi que des techniques de salage plus avancées, en particulier si vous effectuez le hachage dans le niveau d'application):

CREATE TABLE dbo.Users 
(
    UserID INT IDENTITY(1,1) PRIMARY KEY, 
    Username NVARCHAR(255) NOT NULL UNIQUE, 
    PasswordHash VARBINARY(32) NOT NULL 
); 

une procédure pour créer un utilisateur (aucune erreur manipulation ou prévention dupe, juste pseudo).

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 

Maintenant, une procédure pour authentifier un utilisateur.

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 

vous aurait probablement En réalité, effectuer le hachage dans l'application, et de transmettre les valeurs de hachage en tant que VARBINARY (32) - ce qui rend beaucoup plus difficile à « renifler » le mot de passe en texte clair réel où que vous soyez. Et vous ne stockez peut-être pas le sel en texte brut avec le code, mais vous le récupérez ailleurs.

Ceci est certainement plus sûr que de stocker le mot de passe non crypté, mais il supprime la possibilité de récupérer le mot de passe. Gagnant-gagnant à mon avis.

+0

cela fonctionne mais je recommande vraiment d'utiliser un hasing plus avancé avec plusieurs tours etc. comme PBKDF2 ou bcrypt ... – Yahia

+1

Oui, j'ai indiqué dans ma réponse que nous avons utilisé MD5 à l'époque - je voulais dire que ti implique qu'il y a certainement des moyens plus sûrs de le faire. Notez que nous parlons probablement de stocker des mots de passe pour un site de forum ou une base de données de recettes ou quelque chose, pas la CIA. –

+0

Je comprends cela, mais même un site modestement connu pourrait avoir des dommages dans la réputation si l'utilisateur/pw DB est craqué esp. car beaucoup d'utilisateurs utilisent le même PW pour différents sites :-( – Yahia

Questions connexes