diff --git a/src/Microsoft.AspNet.Identity/Crypto.cs b/src/Microsoft.AspNet.Identity/Crypto.cs index 520f2abb86..7ccbfad380 100644 --- a/src/Microsoft.AspNet.Identity/Crypto.cs +++ b/src/Microsoft.AspNet.Identity/Crypto.cs @@ -1,15 +1,14 @@ -#if NET45 - using System; using System.Runtime.CompilerServices; -using System.Security.Cryptography; +using System.Text; +using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Identity { internal static class Crypto { - private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes - private const int PBKDF2SubkeyLength = 256/8; // 256 bits + private const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes + private const int Pbkdf2SubkeyLength = 256/8; // 256 bits private const int SaltSize = 128/8; // 128 bits /* ======================= @@ -30,17 +29,13 @@ namespace Microsoft.AspNet.Identity } // Produce a version 0 (see comment above) text hash. - byte[] salt; - byte[] subkey; - using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount)) - { - salt = deriveBytes.Salt; - subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength); - } - - var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength]; + var salt = new byte[SaltSize]; + CryptRand.FillBuffer(new ArraySegment(salt)); + var passwordBytes = Encoding.UTF8.GetBytes(password); + var subkey = PBKDF2.DeriveKey("SHA1", passwordBytes, salt, Pbkdf2IterCount, Pbkdf2SubkeyLength); + var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength]; Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize); - Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength); + Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength); return Convert.ToBase64String(outputBytes); } @@ -56,26 +51,19 @@ namespace Microsoft.AspNet.Identity throw new ArgumentNullException("password"); } - var hashedPasswordBytes = Convert.FromBase64String(hashedPassword); - // Verify a version 0 (see comment above) text hash. - - if (hashedPasswordBytes.Length != (1 + SaltSize + PBKDF2SubkeyLength) || hashedPasswordBytes[0] != 0x00) + var hashedPasswordBytes = Convert.FromBase64String(hashedPassword); + if (hashedPasswordBytes.Length != (1 + SaltSize + Pbkdf2SubkeyLength) || hashedPasswordBytes[0] != 0x00) { // Wrong length or version header. return false; } - var salt = new byte[SaltSize]; Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, SaltSize); - var storedSubkey = new byte[PBKDF2SubkeyLength]; - Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, PBKDF2SubkeyLength); - - byte[] generatedSubkey; - using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, PBKDF2IterCount)) - { - generatedSubkey = deriveBytes.GetBytes(PBKDF2SubkeyLength); - } + var storedSubkey = new byte[Pbkdf2SubkeyLength]; + Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, Pbkdf2SubkeyLength); + var passwordBytes = Encoding.UTF8.GetBytes(password); + var generatedSubkey = PBKDF2.DeriveKey("SHA1", passwordBytes, salt, Pbkdf2IterCount, Pbkdf2SubkeyLength); return ByteArraysEqual(storedSubkey, generatedSubkey); } @@ -87,12 +75,10 @@ namespace Microsoft.AspNet.Identity { return true; } - if (a == null || b == null || a.Length != b.Length) { return false; } - var areSame = true; for (var i = 0; i < a.Length; i++) { @@ -102,4 +88,3 @@ namespace Microsoft.AspNet.Identity } } } -#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/PasswordHasher.cs b/src/Microsoft.AspNet.Identity/PasswordHasher.cs index 252e815038..9cec887116 100644 --- a/src/Microsoft.AspNet.Identity/PasswordHasher.cs +++ b/src/Microsoft.AspNet.Identity/PasswordHasher.cs @@ -12,11 +12,7 @@ namespace Microsoft.AspNet.Identity /// public virtual string HashPassword(string password) { -#if NET45 return Crypto.HashPassword(password); -#else - return password; -#endif } /// @@ -27,11 +23,7 @@ namespace Microsoft.AspNet.Identity /// public virtual PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { -#if NET45 return Crypto.VerifyHashedPassword(hashedPassword, providedPassword) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed; -#else - return hashedPassword == providedPassword ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed; -#endif } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/UserManager.cs b/src/Microsoft.AspNet.Identity/UserManager.cs index b8768dca9d..f71c3d7663 100644 --- a/src/Microsoft.AspNet.Identity/UserManager.cs +++ b/src/Microsoft.AspNet.Identity/UserManager.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using Microsoft.AspNet.DependencyInjection; using System.Security.Claims; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNet.DependencyInjection; namespace Microsoft.AspNet.Identity { @@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Identity PasswordHasher = serviceProvider.GetService(); UserValidator = serviceProvider.GetService>(); PasswordValidator = serviceProvider.GetService(); - // TODO: validator interfaces, and maybe each optional store as well? Email and SMS services? + // TODO: maybe each optional store as well? Email and SMS services? } /// @@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Identity Store = store; UserValidator = new UserValidator(this); PasswordHasher = new PasswordHasher(); - //ClaimsIdentityFactory = new ClaimsIdentityFactory(); + //TODO: ClaimsIdentityFactory = new ClaimsIdentityFactory(); } /// @@ -243,8 +243,7 @@ namespace Microsoft.AspNet.Identity get { ThrowIfDisposed(); - return false; - //return Store is IUserClaimStore; + return Store is IUserClaimStore; } } diff --git a/src/Microsoft.AspNet.Identity/project.json b/src/Microsoft.AspNet.Identity/project.json index 1c1f0c09df..cf4a473dd3 100644 --- a/src/Microsoft.AspNet.Identity/project.json +++ b/src/Microsoft.AspNet.Identity/project.json @@ -2,7 +2,8 @@ "version" : "0.1-alpha-*", "dependencies": { "Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*", - "System.Security.Claims" : "0.1-alpha-*" + "System.Security.Claims" : "0.1-alpha-*", + "Microsoft.AspNet.Security.DataProtection" : "0.1-alpha-*" }, "configurations": { "net45": {},