Switch to using DataProtection for Crypto
This commit is contained in:
parent
56c67d5ef0
commit
d845ef0b7c
|
|
@ -1,15 +1,14 @@
|
||||||
#if NET45
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Security.Cryptography;
|
using System.Text;
|
||||||
|
using Microsoft.AspNet.Security.DataProtection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity
|
namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
internal static class Crypto
|
internal static class Crypto
|
||||||
{
|
{
|
||||||
private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
|
private const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes
|
||||||
private const int PBKDF2SubkeyLength = 256/8; // 256 bits
|
private const int Pbkdf2SubkeyLength = 256/8; // 256 bits
|
||||||
private const int SaltSize = 128/8; // 128 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.
|
// Produce a version 0 (see comment above) text hash.
|
||||||
byte[] salt;
|
var salt = new byte[SaltSize];
|
||||||
byte[] subkey;
|
CryptRand.FillBuffer(new ArraySegment<byte>(salt));
|
||||||
using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
|
var passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||||
{
|
var subkey = PBKDF2.DeriveKey("SHA1", passwordBytes, salt, Pbkdf2IterCount, Pbkdf2SubkeyLength);
|
||||||
salt = deriveBytes.Salt;
|
var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
|
||||||
subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
|
|
||||||
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
|
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);
|
return Convert.ToBase64String(outputBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,26 +51,19 @@ namespace Microsoft.AspNet.Identity
|
||||||
throw new ArgumentNullException("password");
|
throw new ArgumentNullException("password");
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashedPasswordBytes = Convert.FromBase64String(hashedPassword);
|
|
||||||
|
|
||||||
// Verify a version 0 (see comment above) text hash.
|
// Verify a version 0 (see comment above) text hash.
|
||||||
|
var hashedPasswordBytes = Convert.FromBase64String(hashedPassword);
|
||||||
if (hashedPasswordBytes.Length != (1 + SaltSize + PBKDF2SubkeyLength) || hashedPasswordBytes[0] != 0x00)
|
if (hashedPasswordBytes.Length != (1 + SaltSize + Pbkdf2SubkeyLength) || hashedPasswordBytes[0] != 0x00)
|
||||||
{
|
{
|
||||||
// Wrong length or version header.
|
// Wrong length or version header.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var salt = new byte[SaltSize];
|
var salt = new byte[SaltSize];
|
||||||
Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, SaltSize);
|
Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, SaltSize);
|
||||||
var storedSubkey = new byte[PBKDF2SubkeyLength];
|
var storedSubkey = new byte[Pbkdf2SubkeyLength];
|
||||||
Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, PBKDF2SubkeyLength);
|
Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, Pbkdf2SubkeyLength);
|
||||||
|
var passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||||
byte[] generatedSubkey;
|
var generatedSubkey = PBKDF2.DeriveKey("SHA1", passwordBytes, salt, Pbkdf2IterCount, Pbkdf2SubkeyLength);
|
||||||
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, PBKDF2IterCount))
|
|
||||||
{
|
|
||||||
generatedSubkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
|
|
||||||
}
|
|
||||||
return ByteArraysEqual(storedSubkey, generatedSubkey);
|
return ByteArraysEqual(storedSubkey, generatedSubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,12 +75,10 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a == null || b == null || a.Length != b.Length)
|
if (a == null || b == null || a.Length != b.Length)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var areSame = true;
|
var areSame = true;
|
||||||
for (var i = 0; i < a.Length; i++)
|
for (var i = 0; i < a.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -102,4 +88,3 @@ namespace Microsoft.AspNet.Identity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
@ -12,11 +12,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual string HashPassword(string password)
|
public virtual string HashPassword(string password)
|
||||||
{
|
{
|
||||||
#if NET45
|
|
||||||
return Crypto.HashPassword(password);
|
return Crypto.HashPassword(password);
|
||||||
#else
|
|
||||||
return password;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -27,11 +23,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
|
public virtual PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
|
||||||
{
|
{
|
||||||
#if NET45
|
|
||||||
return Crypto.VerifyHashedPassword(hashedPassword, providedPassword) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
|
return Crypto.VerifyHashedPassword(hashedPassword, providedPassword) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
|
||||||
#else
|
|
||||||
return hashedPassword == providedPassword ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,10 +2,10 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity
|
namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
PasswordHasher = serviceProvider.GetService<IPasswordHasher>();
|
PasswordHasher = serviceProvider.GetService<IPasswordHasher>();
|
||||||
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>();
|
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>();
|
||||||
PasswordValidator = serviceProvider.GetService<IPasswordValidator>();
|
PasswordValidator = serviceProvider.GetService<IPasswordValidator>();
|
||||||
// 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?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
Store = store;
|
Store = store;
|
||||||
UserValidator = new UserValidator<TUser, TKey>(this);
|
UserValidator = new UserValidator<TUser, TKey>(this);
|
||||||
PasswordHasher = new PasswordHasher();
|
PasswordHasher = new PasswordHasher();
|
||||||
//ClaimsIdentityFactory = new ClaimsIdentityFactory<TUser, TKey>();
|
//TODO: ClaimsIdentityFactory = new ClaimsIdentityFactory<TUser, TKey>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -243,8 +243,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
return false;
|
return Store is IUserClaimStore<TUser, TKey>;
|
||||||
//return Store is IUserClaimStore<TUser, TKey>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
"version" : "0.1-alpha-*",
|
"version" : "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
"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": {
|
"configurations": {
|
||||||
"net45": {},
|
"net45": {},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue