Include code coverage and security improvements from windsurf
This commit is contained in:
parent
d282663880
commit
b66984808f
@ -0,0 +1,58 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Strata.Base.Internal.Tests.Security
|
||||
{
|
||||
[TestClass]
|
||||
public class SecurityUtilsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void EncryptValue_WithValidInput_EncryptsAndDecryptsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
string originalValue = "Test sensitive data";
|
||||
string key = "MySecretKey123";
|
||||
|
||||
// Act
|
||||
string encrypted = SecurityUtils.EncryptValue(originalValue, key);
|
||||
string decrypted = SecurityUtils.DecryptValue(encrypted, key);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(originalValue, encrypted, "Encrypted value should be different from original");
|
||||
Assert.AreEqual(originalValue, decrypted, "Decrypted value should match original");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EncryptValue_WithEmptyString_HandlesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
string originalValue = "";
|
||||
string key = "MySecretKey123";
|
||||
|
||||
// Act
|
||||
string encrypted = SecurityUtils.EncryptValue(originalValue, key);
|
||||
string decrypted = SecurityUtils.DecryptValue(encrypted, key);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(originalValue, encrypted, "Encrypted value should be different from empty string");
|
||||
Assert.AreEqual(originalValue, decrypted, "Decrypted value should be empty string");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DecryptValue_WithWrongKey_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
string originalValue = "Test sensitive data";
|
||||
string correctKey = "CorrectKey123";
|
||||
string wrongKey = "WrongKey123";
|
||||
|
||||
// Act
|
||||
string encrypted = SecurityUtils.EncryptValue(originalValue, correctKey);
|
||||
|
||||
// Assert
|
||||
Assert.ThrowsException<System.Security.Cryptography.CryptographicException>(
|
||||
() => SecurityUtils.DecryptValue(encrypted, wrongKey),
|
||||
"Decryption with wrong key should throw CryptographicException"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Strata.Base.Internal.Encryptors;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Strata.Base.Internal.Tests.Security
|
||||
{
|
||||
[TestClass]
|
||||
public class UberEncryptionMethodTests
|
||||
{
|
||||
private const string TestOrgPin = "12345";
|
||||
private const string TestKey = "TestKey123";
|
||||
private const string TestUsername = "testuser";
|
||||
private const string TestPassword = "password123";
|
||||
private static readonly Guid TestUserGuid = Guid.NewGuid();
|
||||
private const string TestSalt = "testsalt";
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// Set up the configuration key for testing
|
||||
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
config.AppSettings.Settings.Remove("UberMonetKey");
|
||||
config.AppSettings.Settings.Add("UberMonetKey", TestKey);
|
||||
config.Save();
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_ReturnsExpectedLength()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UberEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(6, result.Length, "UberMonet hash should be 6 characters long");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_SameInputProducesSameOutput()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UberEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(result1, result2, "Same input should produce same hash");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_DifferentOrgPinsProduceDifferentOutputs()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UberEncryptionMethod();
|
||||
string differentOrgPin = "54321";
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, differentOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(result1, result2, "Different OrgPins should produce different hashes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Strata.Base.Internal.Encryptors;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Strata.Base.Internal.Tests.Security
|
||||
{
|
||||
[TestClass]
|
||||
public class UserGUIDEncryptionMethodTests
|
||||
{
|
||||
private const string TestUsername = "testuser";
|
||||
private const string TestOrgPin = "12345";
|
||||
private const string TestPassword = "password123";
|
||||
private static readonly Guid TestUserGuid = Guid.NewGuid();
|
||||
private const string TestSalt = "testsalt";
|
||||
private const string TestKey = "TestKey123";
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// Set up the configuration key for testing
|
||||
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
config.AppSettings.Settings.Remove("UserGuidEncryptionKey");
|
||||
config.AppSettings.Settings.Add("UserGuidEncryptionKey", TestKey);
|
||||
config.Save();
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_ReturnsNonEmptyString()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserGUIDEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(string.IsNullOrEmpty(result), "Encoded result should not be empty");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_SameInputProducesSameOutput()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserGUIDEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(result1, result2, "Same input should produce same hash");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_DifferentPasswordsProduceDifferentOutputs()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserGUIDEncryptionMethod();
|
||||
string differentPassword = "differentpassword123";
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, differentPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(result1, result2, "Different passwords should produce different hashes");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_DifferentUserGUIDsProduceDifferentOutputs()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserGUIDEncryptionMethod();
|
||||
Guid differentGuid = Guid.NewGuid();
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, differentGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(result1, result2, "Different UserGUIDs should produce different hashes");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_OutputIsBase64String()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserGUIDEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
try
|
||||
{
|
||||
Convert.FromBase64String(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Assert.Fail($"Result should be a valid Base64 string. Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Strata.Base.Internal.Encryptors;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Strata.Base.Internal.Tests.Security
|
||||
{
|
||||
[TestClass]
|
||||
public class UserSaltEncryptionMethodTests
|
||||
{
|
||||
private const string TestUsername = "testuser";
|
||||
private const string TestOrgPin = "12345";
|
||||
private const string TestPassword = "password123";
|
||||
private static readonly Guid TestUserGuid = Guid.NewGuid();
|
||||
private const string TestSalt = "testsalt";
|
||||
private const string TestKey = "TestKey123";
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// Set up the configuration key for testing
|
||||
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
config.AppSettings.Settings.Remove("UserSaltEncryptionKey");
|
||||
config.AppSettings.Settings.Add("UserSaltEncryptionKey", TestKey);
|
||||
config.Save();
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_ReturnsNonEmptyString()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(string.IsNullOrEmpty(result), "Encoded result should not be empty");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_SameInputProducesSameOutput()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(result1, result2, "Same input should produce same hash");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_DifferentPasswordsProduceDifferentOutputs()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
string differentPassword = "differentpassword123";
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, differentPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(result1, result2, "Different passwords should produce different hashes");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_DifferentSaltsProduceDifferentOutputs()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
string differentSalt = "differentsalt";
|
||||
|
||||
// Act
|
||||
string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, differentSalt);
|
||||
|
||||
// Assert
|
||||
Assert.AreNotEqual(result1, result2, "Different salts should produce different hashes");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_OutputIsBase64String()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
|
||||
// Assert
|
||||
try
|
||||
{
|
||||
Convert.FromBase64String(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Assert.Fail($"Result should be a valid Base64 string. Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Encode_OutputHasExpectedLength()
|
||||
{
|
||||
// Arrange
|
||||
var encryptor = new UserSaltEncryptionMethod();
|
||||
|
||||
// Act
|
||||
string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt);
|
||||
byte[] decodedBytes = Convert.FromBase64String(result);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(24, decodedBytes.Length, "Output should be 24 bytes (192 bits)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<AssemblyName>Strata.Base.Internal.Tests</AssemblyName>
|
||||
<RootNamespace>Strata.Base.Internal.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Strata.Base.Internal\Strata.Base.Internal.vbproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
30
vb-migration/Strata.Base.Internal.sln
Normal file
30
vb-migration/Strata.Base.Internal.sln
Normal file
@ -0,0 +1,30 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.0.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Strata.Base.Internal", "Strata.Base.Internal\Strata.Base.Internal.vbproj", "{DB6C7DE1-AB63-4466-93A9-E5C3BDB561B4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Base.Internal.Tests", "Strata.Base.Internal.Tests\Strata.Base.Internal.Tests.csproj", "{11111111-1111-1111-1111-111111111111}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DB6C7DE1-AB63-4466-93A9-E5C3BDB561B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DB6C7DE1-AB63-4466-93A9-E5C3BDB561B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DB6C7DE1-AB63-4466-93A9-E5C3BDB561B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB6C7DE1-AB63-4466-93A9-E5C3BDB561B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11111111-1111-1111-1111-111111111111}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{11111111-1111-1111-1111-111111111111}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5C6D0F1F-E91E-4F6A-9E9F-B3E2DA7F2B4D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@ -1,4 +1,4 @@
|
||||
Imports System.Configuration
|
||||
Imports System.Configuration
|
||||
Imports Strata.Configuration.Client.Models.Jazz
|
||||
|
||||
Namespace Encryptors
|
||||
@ -6,7 +6,7 @@ Namespace Encryptors
|
||||
Public Class UberEncryptionMethod
|
||||
Implements IPasswordEncryptionMethod
|
||||
|
||||
Friend Sub New()
|
||||
Public Sub New()
|
||||
|
||||
End Sub
|
||||
|
||||
@ -17,7 +17,7 @@ Namespace Encryptors
|
||||
End Function
|
||||
|
||||
Private Shared Function GetUberMonet(ByVal aDate As Date, ByVal anOrgPIN As String, ByVal aKey As String) As String
|
||||
Dim ha As New EncryptionUtils.Hasher(EncryptionUtils.Hasher.Provider.SHA1)
|
||||
Dim ha As New EncryptionUtils.Hasher(EncryptionUtils.Hasher.Provider.SHA256)
|
||||
|
||||
Dim lsHashBefore As String
|
||||
Dim lsResult As String
|
||||
@ -38,7 +38,7 @@ Namespace Encryptors
|
||||
|
||||
#Region " IPasswordEncryptionMethod "
|
||||
|
||||
Private Function Encode(ByVal username As String, ByVal anOrgPin As String, ByVal aNewPassword As String, ByVal aUserGUID As System.Guid, aSalt As String) As String Implements IPasswordEncryptionMethod.Encode
|
||||
Public Function Encode(ByVal username As String, ByVal anOrgPin As String, ByVal aNewPassword As String, ByVal aUserGUID As System.Guid, aSalt As String) As String Implements IPasswordEncryptionMethod.Encode
|
||||
Return GetUberMonet(anOrgPin)
|
||||
End Function
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Imports System.Configuration
|
||||
Imports System.Configuration
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Text
|
||||
Imports Strata.Configuration.Client.Models.Jazz
|
||||
@ -30,7 +30,7 @@ Namespace Encryptors
|
||||
Private Shared Function GetHashedValue(ByVal aValue As String) As String
|
||||
|
||||
'Create an instance of the sha encrypter
|
||||
Using hasher As New SHA1Managed
|
||||
Using hasher As HashAlgorithm = SHA256.Create()
|
||||
Return Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(aValue)))
|
||||
End Using
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Imports System.Configuration
|
||||
Imports System.Configuration
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Text
|
||||
Imports Strata.Configuration.Client.Models.Jazz
|
||||
@ -19,7 +19,7 @@ Namespace Encryptors
|
||||
Public Function Encode(ByVal username As String, ByVal anOrgPin As String, ByVal aNewPassword As String, ByVal aUserGUID As System.Guid, aSalt As String) As String Implements IPasswordEncryptionMethod.Encode
|
||||
Dim saltAndPepper As String = aSalt & ConfigurationManager.AppSettings(NameOf(StrataJazzOptions.UserSaltEncryptionKey))
|
||||
|
||||
Using deriveBytes As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(aNewPassword, Encoding.UTF8.GetBytes(saltAndPepper), NUMBER_ITERATIONS)
|
||||
Using deriveBytes As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(aNewPassword, Encoding.UTF8.GetBytes(saltAndPepper), NUMBER_ITERATIONS, HashAlgorithmName.SHA256)
|
||||
Dim password As Byte() = deriveBytes.GetBytes(24)
|
||||
|
||||
Return Convert.ToBase64String(password)
|
||||
|
||||
@ -13,7 +13,7 @@ Namespace EncryptionUtils
|
||||
''' infeasible to find two distinct inputs that hash to the same value. Hash functions
|
||||
''' are commonly used with digital signatures and for data integrity.
|
||||
''' </summary>
|
||||
Friend Class Hasher
|
||||
Public Class Hasher
|
||||
|
||||
''' <summary>
|
||||
''' Type of hash; some are security oriented, others are fast and simple
|
||||
@ -44,7 +44,7 @@ Namespace EncryptionUtils
|
||||
Private _Hash As HashAlgorithm
|
||||
Private _HashValue As New Data
|
||||
|
||||
Private Sub New()
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
@ -53,15 +53,17 @@ Namespace EncryptionUtils
|
||||
Friend Sub New(ByVal p As Provider)
|
||||
Select Case p
|
||||
Case Provider.MD5
|
||||
_Hash = New MD5CryptoServiceProvider
|
||||
_Hash = MD5.Create()
|
||||
Case Provider.SHA1
|
||||
_Hash = New SHA1Managed
|
||||
_Hash = SHA1.Create()
|
||||
Case Provider.SHA256
|
||||
_Hash = New SHA256Managed
|
||||
_Hash = SHA256.Create()
|
||||
Case Provider.SHA384
|
||||
_Hash = New SHA384Managed
|
||||
_Hash = SHA384.Create()
|
||||
Case Provider.SHA512
|
||||
_Hash = New SHA512Managed
|
||||
_Hash = SHA512.Create()
|
||||
Case Else
|
||||
_Hash = SHA256.Create() ' Default to SHA256 for unknown providers
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
@ -124,22 +126,22 @@ Namespace EncryptionUtils
|
||||
Private Const _BufferSize As Integer = 2048
|
||||
|
||||
Friend Enum Provider
|
||||
''' <summary>
|
||||
''' The Data Encryption Standard provider supports a 64 bit key only
|
||||
''' </summary>
|
||||
<Obsolete("MD5 is cryptographically broken and unsuitable for further use. Use SHA256 or stronger.")>
|
||||
MD5
|
||||
<Obsolete("SHA1 is cryptographically broken and unsuitable for further use. Use SHA256 or stronger.")>
|
||||
SHA1
|
||||
SHA256
|
||||
SHA384
|
||||
SHA512
|
||||
<Obsolete("DES is cryptographically broken and unsuitable for further use. Use AES instead.")>
|
||||
DES
|
||||
''' <summary>
|
||||
''' The Rivest Cipher 2 provider supports keys ranging from 40 to 128 bits, default is 128 bits
|
||||
''' </summary>
|
||||
<Obsolete("RC2 is cryptographically broken and unsuitable for further use. Use AES instead.")>
|
||||
RC2
|
||||
''' <summary>
|
||||
''' The Rijndael (also known as AES) provider supports keys of 128, 192, or 256 bits with a default of 256 bits
|
||||
''' </summary>
|
||||
<Obsolete("Use AES instead. This enum value will be removed in a future version.")>
|
||||
Rijndael
|
||||
''' <summary>
|
||||
''' The TripleDES provider (also known as 3DES) supports keys of 128 or 192 bits with a default of 192 bits
|
||||
''' </summary>
|
||||
<Obsolete("TripleDES is not recommended for new applications. Use AES instead.")>
|
||||
TripleDES
|
||||
AES
|
||||
End Enum
|
||||
|
||||
Private _data As Data
|
||||
@ -158,13 +160,15 @@ Namespace EncryptionUtils
|
||||
Friend Sub New(ByVal provider As Provider, Optional ByVal useDefaultInitializationVector As Boolean = True)
|
||||
Select Case provider
|
||||
Case Provider.DES
|
||||
_crypto = New DESCryptoServiceProvider
|
||||
_crypto = DES.Create()
|
||||
Case Provider.RC2
|
||||
_crypto = New RC2CryptoServiceProvider
|
||||
Case Provider.Rijndael
|
||||
_crypto = New RijndaelManaged
|
||||
_crypto = RC2.Create()
|
||||
Case Provider.Rijndael, Provider.AES
|
||||
_crypto = Aes.Create()
|
||||
Case Provider.TripleDES
|
||||
_crypto = New TripleDESCryptoServiceProvider
|
||||
_crypto = TripleDES.Create()
|
||||
Case Else
|
||||
_crypto = Aes.Create() ' Default to AES for unknown providers
|
||||
End Select
|
||||
|
||||
'-- make sure key and IV are always set, no matter what
|
||||
@ -272,8 +276,12 @@ Namespace EncryptionUtils
|
||||
Throw New CryptographicException("No initialization vector was provided for the decryption operation!")
|
||||
End If
|
||||
End If
|
||||
_crypto.Key = _key.Bytes
|
||||
_crypto.IV = _iv.Bytes
|
||||
Try
|
||||
_crypto.Key = _key.Bytes
|
||||
_crypto.IV = _iv.Bytes
|
||||
Catch ex As CryptographicException
|
||||
Throw New CryptographicException("Invalid key or initialization vector.", ex)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
@ -384,20 +392,19 @@ Namespace EncryptionUtils
|
||||
''' Decrypts the specified data using preset key and preset initialization vector
|
||||
''' </summary>
|
||||
Friend Function Decrypt(ByVal encryptedData As Data) As Data
|
||||
Dim ms As New System.IO.MemoryStream(encryptedData.Bytes, 0, encryptedData.Bytes.Length)
|
||||
Dim b() As Byte = New Byte(encryptedData.Bytes.Length - 1) {}
|
||||
|
||||
ValidateKeyAndIv(False)
|
||||
Dim cs As New CryptoStream(ms, _crypto.CreateDecryptor(), CryptoStreamMode.Read)
|
||||
|
||||
Try
|
||||
cs.Read(b, 0, encryptedData.Bytes.Length - 1)
|
||||
Catch ex As CryptographicException
|
||||
Throw New CryptographicException("Unable to decrypt data. The provided key may be invalid.", ex)
|
||||
Finally
|
||||
cs.Close()
|
||||
End Try
|
||||
Return New Data(b)
|
||||
Using ms As New System.IO.MemoryStream(encryptedData.Bytes, 0, encryptedData.Bytes.Length)
|
||||
ValidateKeyAndIv(False)
|
||||
Using cs As New CryptoStream(ms, _crypto.CreateDecryptor(), CryptoStreamMode.Read)
|
||||
Using outputMs As New MemoryStream()
|
||||
Try
|
||||
cs.CopyTo(outputMs)
|
||||
Return New Data(outputMs.ToArray())
|
||||
Catch ex As CryptographicException
|
||||
Throw New CryptographicException("Unable to decrypt data. The provided key may be invalid.", ex)
|
||||
End Try
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Function
|
||||
|
||||
End Class
|
||||
@ -421,7 +428,12 @@ Namespace EncryptionUtils
|
||||
''' <summary>
|
||||
''' Determines the default text encoding across ALL Data instances
|
||||
''' </summary>
|
||||
Friend Shared DefaultEncoding As Text.Encoding = System.Text.Encoding.GetEncoding("Windows-1252")
|
||||
Friend Shared DefaultEncoding As Text.Encoding
|
||||
|
||||
Shared Sub New()
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)
|
||||
DefaultEncoding = System.Text.Encoding.GetEncoding("Windows-1252")
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Determines the default text encoding for this Data instance
|
||||
|
||||
@ -1,16 +1,26 @@
|
||||
Public Class SecurityUtils
|
||||
|
||||
#Region " Declarations "
|
||||
|
||||
Private Const ENCRYPTION_KEY_SUFFIX As String = "SDT"
|
||||
Private Const KEY_SIZE_BYTES As Integer = 32 ' 256 bits for AES-256
|
||||
#End Region
|
||||
|
||||
#Region " Methods "
|
||||
|
||||
Private Shared Function PadKey(key As String) As String
|
||||
Dim paddedKey As String = key & ENCRYPTION_KEY_SUFFIX
|
||||
If paddedKey.Length < KEY_SIZE_BYTES Then
|
||||
paddedKey = paddedKey.PadRight(KEY_SIZE_BYTES, "X"c)
|
||||
ElseIf paddedKey.Length > KEY_SIZE_BYTES Then
|
||||
paddedKey = paddedKey.Substring(0, KEY_SIZE_BYTES)
|
||||
End If
|
||||
Return paddedKey
|
||||
End Function
|
||||
|
||||
Public Shared Function EncryptValue(value As String, key As String) As String
|
||||
Dim encryption As New EncryptionUtils.SymmetricEncryptor(EncryptionUtils.SymmetricEncryptor.Provider.Rijndael)
|
||||
|
||||
Return encryption.Encrypt(New EncryptionUtils.Data(value), New EncryptionUtils.Data(key & ENCRYPTION_KEY_SUFFIX)).ToBase64
|
||||
|
||||
Return encryption.Encrypt(New EncryptionUtils.Data(value), New EncryptionUtils.Data(PadKey(key))).ToBase64
|
||||
End Function
|
||||
|
||||
Public Shared Function DecryptValue(encryptedValue As String, key As String) As String
|
||||
@ -20,7 +30,7 @@ Public Class SecurityUtils
|
||||
Dim encryptedData As EncryptionUtils.Data = New EncryptionUtils.Data()
|
||||
encryptedData.Base64 = encryptedValue
|
||||
|
||||
Return encryption.Decrypt(encryptedData, New EncryptionUtils.Data(key & ENCRYPTION_KEY_SUFFIX)).Text
|
||||
Return encryption.Decrypt(encryptedData, New EncryptionUtils.Data(PadKey(key))).Text
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user