Include code coverage and security improvements from windsurf

This commit is contained in:
Jorge Burgos 2025-01-30 21:20:04 -05:00
parent d282663880
commit b66984808f
12 changed files with 491 additions and 60 deletions

View File

@ -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"
);
}
}
}

View File

@ -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");
}
}
}

View File

@ -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}");
}
}
}
}

View File

@ -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)");
}
}
}

View File

@ -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>

View 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

View File

@ -1,4 +1,4 @@
Imports System.Configuration Imports System.Configuration
Imports Strata.Configuration.Client.Models.Jazz Imports Strata.Configuration.Client.Models.Jazz
Namespace Encryptors Namespace Encryptors
@ -6,7 +6,7 @@ Namespace Encryptors
Public Class UberEncryptionMethod Public Class UberEncryptionMethod
Implements IPasswordEncryptionMethod Implements IPasswordEncryptionMethod
Friend Sub New() Public Sub New()
End Sub End Sub
@ -17,7 +17,7 @@ Namespace Encryptors
End Function End Function
Private Shared Function GetUberMonet(ByVal aDate As Date, ByVal anOrgPIN As String, ByVal aKey As String) As String 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 lsHashBefore As String
Dim lsResult As String Dim lsResult As String
@ -38,7 +38,7 @@ Namespace Encryptors
#Region " IPasswordEncryptionMethod " #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) Return GetUberMonet(anOrgPin)
End Function End Function

View File

@ -1,4 +1,4 @@
Imports System.Configuration Imports System.Configuration
Imports System.Security.Cryptography Imports System.Security.Cryptography
Imports System.Text Imports System.Text
Imports Strata.Configuration.Client.Models.Jazz Imports Strata.Configuration.Client.Models.Jazz
@ -30,7 +30,7 @@ Namespace Encryptors
Private Shared Function GetHashedValue(ByVal aValue As String) As String Private Shared Function GetHashedValue(ByVal aValue As String) As String
'Create an instance of the sha encrypter '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))) Return Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(aValue)))
End Using End Using

View File

@ -1,4 +1,4 @@
Imports System.Configuration Imports System.Configuration
Imports System.Security.Cryptography Imports System.Security.Cryptography
Imports System.Text Imports System.Text
Imports Strata.Configuration.Client.Models.Jazz 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 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)) 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) Dim password As Byte() = deriveBytes.GetBytes(24)
Return Convert.ToBase64String(password) Return Convert.ToBase64String(password)

View File

@ -13,7 +13,7 @@ Namespace EncryptionUtils
''' infeasible to find two distinct inputs that hash to the same value. Hash functions ''' infeasible to find two distinct inputs that hash to the same value. Hash functions
''' are commonly used with digital signatures and for data integrity. ''' are commonly used with digital signatures and for data integrity.
''' </summary> ''' </summary>
Friend Class Hasher Public Class Hasher
''' <summary> ''' <summary>
''' Type of hash; some are security oriented, others are fast and simple ''' Type of hash; some are security oriented, others are fast and simple
@ -44,7 +44,7 @@ Namespace EncryptionUtils
Private _Hash As HashAlgorithm Private _Hash As HashAlgorithm
Private _HashValue As New Data Private _HashValue As New Data
Private Sub New() Friend Sub New()
End Sub End Sub
''' <summary> ''' <summary>
@ -53,15 +53,17 @@ Namespace EncryptionUtils
Friend Sub New(ByVal p As Provider) Friend Sub New(ByVal p As Provider)
Select Case p Select Case p
Case Provider.MD5 Case Provider.MD5
_Hash = New MD5CryptoServiceProvider _Hash = MD5.Create()
Case Provider.SHA1 Case Provider.SHA1
_Hash = New SHA1Managed _Hash = SHA1.Create()
Case Provider.SHA256 Case Provider.SHA256
_Hash = New SHA256Managed _Hash = SHA256.Create()
Case Provider.SHA384 Case Provider.SHA384
_Hash = New SHA384Managed _Hash = SHA384.Create()
Case Provider.SHA512 Case Provider.SHA512
_Hash = New SHA512Managed _Hash = SHA512.Create()
Case Else
_Hash = SHA256.Create() ' Default to SHA256 for unknown providers
End Select End Select
End Sub End Sub
@ -124,22 +126,22 @@ Namespace EncryptionUtils
Private Const _BufferSize As Integer = 2048 Private Const _BufferSize As Integer = 2048
Friend Enum Provider Friend Enum Provider
''' <summary> <Obsolete("MD5 is cryptographically broken and unsuitable for further use. Use SHA256 or stronger.")>
''' The Data Encryption Standard provider supports a 64 bit key only MD5
''' </summary> <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 DES
''' <summary> <Obsolete("RC2 is cryptographically broken and unsuitable for further use. Use AES instead.")>
''' The Rivest Cipher 2 provider supports keys ranging from 40 to 128 bits, default is 128 bits
''' </summary>
RC2 RC2
''' <summary> <Obsolete("Use AES instead. This enum value will be removed in a future version.")>
''' The Rijndael (also known as AES) provider supports keys of 128, 192, or 256 bits with a default of 256 bits
''' </summary>
Rijndael Rijndael
''' <summary> <Obsolete("TripleDES is not recommended for new applications. Use AES instead.")>
''' The TripleDES provider (also known as 3DES) supports keys of 128 or 192 bits with a default of 192 bits
''' </summary>
TripleDES TripleDES
AES
End Enum End Enum
Private _data As Data Private _data As Data
@ -158,13 +160,15 @@ Namespace EncryptionUtils
Friend Sub New(ByVal provider As Provider, Optional ByVal useDefaultInitializationVector As Boolean = True) Friend Sub New(ByVal provider As Provider, Optional ByVal useDefaultInitializationVector As Boolean = True)
Select Case provider Select Case provider
Case Provider.DES Case Provider.DES
_crypto = New DESCryptoServiceProvider _crypto = DES.Create()
Case Provider.RC2 Case Provider.RC2
_crypto = New RC2CryptoServiceProvider _crypto = RC2.Create()
Case Provider.Rijndael Case Provider.Rijndael, Provider.AES
_crypto = New RijndaelManaged _crypto = Aes.Create()
Case Provider.TripleDES Case Provider.TripleDES
_crypto = New TripleDESCryptoServiceProvider _crypto = TripleDES.Create()
Case Else
_crypto = Aes.Create() ' Default to AES for unknown providers
End Select End Select
'-- make sure key and IV are always set, no matter what '-- 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!") Throw New CryptographicException("No initialization vector was provided for the decryption operation!")
End If End If
End If End If
_crypto.Key = _key.Bytes Try
_crypto.IV = _iv.Bytes _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 End Sub
''' <summary> ''' <summary>
@ -384,20 +392,19 @@ Namespace EncryptionUtils
''' Decrypts the specified data using preset key and preset initialization vector ''' Decrypts the specified data using preset key and preset initialization vector
''' </summary> ''' </summary>
Friend Function Decrypt(ByVal encryptedData As Data) As Data Friend Function Decrypt(ByVal encryptedData As Data) As Data
Dim ms As New System.IO.MemoryStream(encryptedData.Bytes, 0, encryptedData.Bytes.Length) Using ms As New System.IO.MemoryStream(encryptedData.Bytes, 0, encryptedData.Bytes.Length)
Dim b() As Byte = New Byte(encryptedData.Bytes.Length - 1) {} ValidateKeyAndIv(False)
Using cs As New CryptoStream(ms, _crypto.CreateDecryptor(), CryptoStreamMode.Read)
ValidateKeyAndIv(False) Using outputMs As New MemoryStream()
Dim cs As New CryptoStream(ms, _crypto.CreateDecryptor(), CryptoStreamMode.Read) Try
cs.CopyTo(outputMs)
Try Return New Data(outputMs.ToArray())
cs.Read(b, 0, encryptedData.Bytes.Length - 1) Catch ex As CryptographicException
Catch ex As CryptographicException Throw New CryptographicException("Unable to decrypt data. The provided key may be invalid.", ex)
Throw New CryptographicException("Unable to decrypt data. The provided key may be invalid.", ex) End Try
Finally End Using
cs.Close() End Using
End Try End Using
Return New Data(b)
End Function End Function
End Class End Class
@ -421,7 +428,12 @@ Namespace EncryptionUtils
''' <summary> ''' <summary>
''' Determines the default text encoding across ALL Data instances ''' Determines the default text encoding across ALL Data instances
''' </summary> ''' </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> ''' <summary>
''' Determines the default text encoding for this Data instance ''' Determines the default text encoding for this Data instance

View File

@ -1,16 +1,26 @@
Public Class SecurityUtils Public Class SecurityUtils
#Region " Declarations " #Region " Declarations "
Private Const ENCRYPTION_KEY_SUFFIX As String = "SDT" Private Const ENCRYPTION_KEY_SUFFIX As String = "SDT"
Private Const KEY_SIZE_BYTES As Integer = 32 ' 256 bits for AES-256
#End Region #End Region
#Region " Methods " #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 Public Shared Function EncryptValue(value As String, key As String) As String
Dim encryption As New EncryptionUtils.SymmetricEncryptor(EncryptionUtils.SymmetricEncryptor.Provider.Rijndael) 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 End Function
Public Shared Function DecryptValue(encryptedValue As String, key As String) As String 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() Dim encryptedData As EncryptionUtils.Data = New EncryptionUtils.Data()
encryptedData.Base64 = encryptedValue 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 Function
#End Region #End Region

File diff suppressed because one or more lines are too long