Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

173 lines
6.0 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.Test
{
/// <summary>
///This is a test class for CryptoTest and is intended
///to contain all CryptoTest Unit Tests
///</summary>
public class CryptoTest
{
[Fact]
public void SHA256HashTest_ReturnsValidData()
{
string data = "foo bar";
string expected = "FBC1A9F858EA9E177916964BD88C3D37B91A1E84412765E29950777F265C4B75";
string actual;
actual = Crypto.SHA256(data);
Assert.Equal(expected, actual);
actual = Crypto.Hash(Encoding.UTF8.GetBytes(data));
Assert.Equal(expected, actual);
}
[Fact]
public void GenerateSaltTest()
{
string salt = Crypto.GenerateSalt();
salt = Crypto.GenerateSalt(64);
Assert.Equal(24, Crypto.GenerateSalt().Length);
Assert.Equal(12, Crypto.GenerateSalt(8).Length);
Assert.Equal(88, Crypto.GenerateSalt(64).Length);
Assert.Equal(44, Crypto.GenerateSalt(32).Length);
}
[Fact]
public void HashPassword_PasswordGeneration()
{
// Act - call helper directly
string generatedHash = Crypto.HashPassword("my-password");
byte[] salt = new byte[16];
Buffer.BlockCopy(Convert.FromBase64String(generatedHash), 1, salt, 0, 16); // extract salt from generated hash
// Act - perform PBKDF2 directly
string generatedHash2;
using (var ms = new MemoryStream())
{
using (var bw = new BinaryWriter(ms))
{
using (var deriveBytes = new Rfc2898DeriveBytes("my-password", salt, iterations: 1000))
{
bw.Write((byte)0x00); // version identifier
bw.Write(salt); // salt
bw.Write(deriveBytes.GetBytes(32)); // subkey
}
generatedHash2 = Convert.ToBase64String(ms.ToArray());
}
}
// Assert
Assert.Equal(generatedHash2, generatedHash);
}
[Fact]
public void HashPassword_RoundTripping()
{
// Act & assert
string password = "ImPepper";
Assert.True(Crypto.VerifyHashedPassword(Crypto.HashPassword(password), password));
Assert.False(Crypto.VerifyHashedPassword(Crypto.HashPassword(password), "ImSalt"));
Assert.False(Crypto.VerifyHashedPassword(Crypto.HashPassword("Impepper"), password));
}
[Fact]
public void VerifyHashedPassword_CorrectPassword_ReturnsTrue()
{
// Arrange
string hashedPassword = "ALyuoraY/cIWD1hjo+K81/pf83qo6Q6T+UBYcXN9P3A9WHLvEY10f+lwW5qPG6h9xw=="; // this is for 'my-password'
// Act
bool retVal = Crypto.VerifyHashedPassword(hashedPassword, "my-password");
// Assert
Assert.True(retVal);
}
[Fact]
public void VerifyHashedPassword_IncorrectPassword_ReturnsFalse()
{
// Arrange
string hashedPassword = "ALyuoraY/cIWD1hjo+K81/pf83qo6Q6T+UBYcXN9P3A9WHLvEY10f+lwW5qPG6h9xw=="; // this is for 'my-password'
// Act
bool retVal = Crypto.VerifyHashedPassword(hashedPassword, "some-other-password");
// Assert
Assert.False(retVal);
}
[Fact]
public void VerifyHashedPassword_InvalidPasswordHash_ReturnsFalse()
{
// Arrange
string hashedPassword = "AAECAw=="; // this is an invalid password hash
// Act
bool retVal = Crypto.VerifyHashedPassword(hashedPassword, "hello-world");
// Assert
Assert.False(retVal);
}
[Fact]
public void MD5HashTest_ReturnsValidData()
{
string data = "foo bar";
string expected = "327B6F07435811239BC47E1544353273";
string actual;
actual = Crypto.Hash(data, algorithm: "md5");
Assert.Equal(expected, actual);
actual = Crypto.Hash(Encoding.UTF8.GetBytes(data), algorithm: "MD5");
Assert.Equal(expected, actual);
}
[Fact]
public void SHA1HashTest_ReturnsValidData()
{
string data = "foo bar";
string expected = "3773DEA65156909838FA6C22825CAFE090FF8030";
string actual;
actual = Crypto.SHA1(data);
Assert.Equal(expected, actual);
actual = Crypto.Hash(Encoding.UTF8.GetBytes(data), algorithm: "sha1");
Assert.Equal(expected, actual);
}
[Fact]
public void SHA1HashTest_WithNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() => Crypto.SHA1((string)null));
Assert.Throws<ArgumentNullException>(() => Crypto.Hash((byte[])null, algorithm: "SHa1"));
}
[Fact]
public void SHA256HashTest_WithNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() => Crypto.SHA256((string)null));
Assert.Throws<ArgumentNullException>(() => Crypto.Hash((byte[])null, algorithm: "sHa256"));
}
[Fact]
public void MD5HashTest_WithNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() => Crypto.Hash((string)null, algorithm: "mD5"));
Assert.Throws<ArgumentNullException>(() => Crypto.Hash((byte[])null, algorithm: "mD5"));
}
[Fact]
public void HashWithUnknownAlg_ThrowsException()
{
Assert.Throws<InvalidOperationException>(() => Crypto.Hash("sdflksd", algorithm: "hao"), "The hash algorithm 'hao' is not supported, valid values are: sha256, sha1, md5");
}
}
}