diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/DsaEncryptor.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/DsaEncryptor.cs
index f2029ca11f..5f45d5165b 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/DsaEncryptor.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/DsaEncryptor.cs
@@ -1,4 +1,5 @@
-using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
@@ -11,9 +12,9 @@ public static class DsaEncryptor
public static AsymmetricCipherKeyPair GenerateDsaKeyPair()
{
// Create DSA parameters
- var dsaParamsGenerator = new DsaParametersGenerator();
+ var dsaParamsGenerator = new DsaParametersGenerator(new Sha256Digest());
var random = new SecureRandom();
- dsaParamsGenerator.Init(1024, 80, random); // key size: 1024 bits, certainty: 80
+ dsaParamsGenerator.Init(new DsaParameterGenerationParameters(2048, 256, 80, random)); // key size: 2048 bits, q size: 256 bits, certainty: 80
// Generate DSA key pair
var dsaParams = dsaParamsGenerator.GenerateParameters();
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/RsaEncryptor.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/RsaEncryptor.cs
index 720e7e5ea6..f10c91b560 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/RsaEncryptor.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/AsymmetricEncryption/RsaEncryptor.cs
@@ -1,4 +1,5 @@
-using Org.BouncyCastle.Crypto.Encodings;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto;
@@ -21,7 +22,7 @@ public static byte[] RsaEncrypt(string input, AsymmetricKeyParameter publicKey)
{
var inputBytes = Encoding.UTF8.GetBytes(input);
- var cipher = new Pkcs1Encoding(new RsaEngine());
+ var cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest());
cipher.Init(true, publicKey);
@@ -30,7 +31,7 @@ public static byte[] RsaEncrypt(string input, AsymmetricKeyParameter publicKey)
public static string RsaDecrypt(byte[] encryptedBytes, AsymmetricKeyParameter privateKey)
{
- var cipher = new Pkcs1Encoding(new RsaEngine());
+ var cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest());
// Initialize the cipher for decryption with the private key
cipher.Init(false, privateKey);
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/BouncyCastleCryptography.csproj b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/BouncyCastleCryptography.csproj
index 02341e438a..610cd0d701 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/BouncyCastleCryptography.csproj
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/BouncyCastleCryptography.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net10.0
enable
enable
@@ -14,7 +14,7 @@
-
+
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/Program.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/Program.cs
index f946250fda..8ed4dc0866 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/Program.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/Program.cs
@@ -3,17 +3,18 @@
using BouncyCastleCryptography.SymmetricEncryption;
var input = "Hello, Bouncy Castle!";
+var secretValue = "This is my password! Dont read me!";
// HASHING
Console.WriteLine("Hashing:");
-var hash = Md5Hasher.Md5Hash(input);
+var hash = Md5Hasher.Md5Hash(secretValue);
var hashAsStr = Convert.ToBase64String(hash);
Console.WriteLine("MD5 hash result: " + hashAsStr);
-hash = ShaHasher.ShaHash(input);
+hash = ShaHasher.ShaHash(secretValue);
hashAsStr = Convert.ToBase64String(hash);
@@ -32,7 +33,7 @@
var password = "mysecretpassword";
-encryptedData = BlowfishEncryptor.BlowfishEncrypt(input, password, out byte[] iv2);
+encryptedData = BlowfishEncryptor.BlowfishEncrypt(input, password, out byte[] salt, out byte[] iv2);
encryptedString = Convert.ToBase64String(encryptedData);
@@ -55,7 +56,7 @@
var signature = DsaEncryptor.DsaSign(input, keyPair2.Private);
-var signatureAsStr = Convert.ToBase64String(encryptedData);
+var signatureAsStr = Convert.ToBase64String(signature);
var isSignatureValid = DsaEncryptor.DsaVerify(input, signature, keyPair2.Public);
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/AesEncryptor.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/AesEncryptor.cs
index feacb6bfaa..31fc430c60 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/AesEncryptor.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/AesEncryptor.cs
@@ -35,8 +35,6 @@ public static string AesDecrypt(byte[] key, byte[] iv, byte[] encryptedBytes)
// Decrypt the encrypted data
var decryptedBytes = cipher.DoFinal(encryptedBytes);
- var decryptedString = Encoding.UTF8.GetString(decryptedBytes);
-
- return decryptedString;
+ return Encoding.UTF8.GetString(decryptedBytes);
}
}
\ No newline at end of file
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/BlowfishEncryptor.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/BlowfishEncryptor.cs
index 3ca5078c87..31a520dc26 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/BlowfishEncryptor.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptography/SymmetricEncryption/BlowfishEncryptor.cs
@@ -1,46 +1,53 @@
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
-using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-namespace BouncyCastleCryptography.SymmetricEncryption
+namespace BouncyCastleCryptography.SymmetricEncryption;
+
+public static class BlowfishEncryptor
{
- public class BlowfishEncryptor
+ private const int Iterations = 600_000;
+
+ public static byte[] BlowfishEncrypt(string input, string password, out byte[] salt, out byte[] iv)
{
- public static byte[] BlowfishEncrypt(string input, string password, out byte[] iv)
- {
- var inputBytes = Encoding.UTF8.GetBytes(input);
+ var inputBytes = Encoding.UTF8.GetBytes(input);
+
+ var random = new SecureRandom();
+ salt = new byte[16];
+ random.NextBytes(salt);
+ iv = new byte[8]; // Blowfish uses an 8-byte (64-bit) IV
+ random.NextBytes(iv);
+
+ var cipher = CipherUtilities.GetCipher("Blowfish/CBC/PKCS7Padding");
- var random = new SecureRandom();
- iv = new byte[8]; // Blowfish uses an 8-byte (64-bit) IV
- random.NextBytes(iv);
+ var keyParam = DeriveKey(password, salt);
- var cipher = CipherUtilities.GetCipher("Blowfish/CBC/PKCS7Padding");
+ cipher.Init(true, new ParametersWithIV(keyParam, iv));
- var keyBytes = Encoding.UTF8.GetBytes(password);
- var keyParam = new KeyParameter(keyBytes);
+ return cipher.DoFinal(inputBytes);
+ }
- cipher.Init(true, new ParametersWithIV(keyParam, iv));
+ public static string BlowfishDecrypt(byte[] encryptedBytes, string password, byte[] salt, byte[] iv)
+ {
+ var cipher = CipherUtilities.GetCipher("Blowfish/CBC/PKCS7Padding");
- return cipher.DoFinal(inputBytes);
- }
+ var keyParam = DeriveKey(password, salt);
- public static string BlowfishDecrypt(byte[] encryptedBytes, string password, byte[] iv)
- {
- var cipher = CipherUtilities.GetCipher("Blowfish/CBC/PKCS7Padding");
+ cipher.Init(false, new ParametersWithIV(keyParam, iv));
- var keyBytes = Encoding.UTF8.GetBytes(password);
- var keyParam = new KeyParameter(keyBytes);
+ var plainBytes = cipher.DoFinal(encryptedBytes);
- cipher.Init(false, new ParametersWithIV(keyParam, iv));
+ return Encoding.UTF8.GetString(plainBytes);
+ }
- var plainBytes = cipher.DoFinal(encryptedBytes);
+ private static KeyParameter DeriveKey(string password, byte[] salt)
+ {
+ // PBKDF2 with HMAC-SHA256 stretches the password and salt into a 128-bit key
+ var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
+ generator.Init(Encoding.UTF8.GetBytes(password), salt, Iterations);
- return Encoding.UTF8.GetString(plainBytes);
- }
+ return (KeyParameter)generator.GenerateDerivedParameters("Blowfish", 128);
}
}
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/BouncyCastleCryptographyTests.csproj b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/BouncyCastleCryptographyTests.csproj
index 2544f81751..9ecff50130 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/BouncyCastleCryptographyTests.csproj
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/BouncyCastleCryptographyTests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
enable
@@ -10,10 +10,10 @@
-
-
-
-
+
+
+
+
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/HashingUnitTests.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/HashingUnitTests.cs
index 71411fff46..b90879f48e 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/HashingUnitTests.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/HashingUnitTests.cs
@@ -8,7 +8,7 @@ public class HashingUnitTests
[TestMethod]
public void GivenSecretData_WhenMd5IsUsed_ThenSecretIsHashed()
{
- var secretValue = "This is my pasword! Dont read me!";
+ var secretValue = "This is my password! Dont read me!";
var hash = Md5Hasher.Md5Hash(secretValue);
@@ -18,7 +18,7 @@ public void GivenSecretData_WhenMd5IsUsed_ThenSecretIsHashed()
[TestMethod]
public void GivenSecretData_WhenMd5HashingMultipleTimes_ThenResultIsDeterministic()
{
- var secretValue = "This is my pasword! Dont read me!";
+ var secretValue = "This is my password! Dont read me!";
var hash = Md5Hasher.Md5Hash(secretValue);
@@ -30,7 +30,7 @@ public void GivenSecretData_WhenMd5HashingMultipleTimes_ThenResultIsDeterministi
[TestMethod]
public void GivenSecretData_WhenShaIsUsed_ThenSecretIsHashed()
{
- var secretValue = "This is my pasword! Dont read me!";
+ var secretValue = "This is my password! Dont read me!";
var hash = ShaHasher.ShaHash(secretValue);
@@ -40,7 +40,7 @@ public void GivenSecretData_WhenShaIsUsed_ThenSecretIsHashed()
[TestMethod]
public void GivenSecretData_WhenShaHashingMultipleTimes_ThenResultIsDeterministic()
{
- var secretValue = "This is my pasword! Dont read me!";
+ var secretValue = "This is my password! Dont read me!";
var hash = ShaHasher.ShaHash(secretValue);
@@ -48,4 +48,24 @@ public void GivenSecretData_WhenShaHashingMultipleTimes_ThenResultIsDeterministi
CollectionAssert.AreEqual(hash, hash2);
}
+
+ [TestMethod]
+ public void GivenSecretData_WhenMd5IsUsed_ThenHashMatchesKnownValue()
+ {
+ var secretValue = "This is my password! Dont read me!";
+
+ var hash = Md5Hasher.Md5Hash(secretValue);
+
+ Assert.AreEqual("l5aMGrOOPOxm6i6cRK/sqA==", Convert.ToBase64String(hash));
+ }
+
+ [TestMethod]
+ public void GivenSecretData_WhenShaIsUsed_ThenHashMatchesKnownValue()
+ {
+ var secretValue = "This is my password! Dont read me!";
+
+ var hash = ShaHasher.ShaHash(secretValue);
+
+ Assert.AreEqual("SSNYFZG3vQSGtXqZVaSZry4QBm4uueLwegd/gd6H8ns=", Convert.ToBase64String(hash));
+ }
}
\ No newline at end of file
diff --git a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/SymmetricEncryptionUnitTests.cs b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/SymmetricEncryptionUnitTests.cs
index 752d0ea580..f944c48020 100644
--- a/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/SymmetricEncryptionUnitTests.cs
+++ b/authorization-dotnet/BouncyCastleCryptography/BouncyCastleCryptographyTests/SymmetricEncryptionUnitTests.cs
@@ -10,7 +10,7 @@ public void GivenSecretData_WhenAesEncrypting_ThenDataIsEncrypted()
{
var input = "Hello, Bouncy Castle!";
- var encryptedData = AesEncryptor.AesEncrypt(input, out byte[] iv, out byte[] key);
+ var encryptedData = AesEncryptor.AesEncrypt(input, out _, out _);
var encryptedString = Convert.ToBase64String(encryptedData);
@@ -39,7 +39,7 @@ public void GivenSecretData_WhenBlowfishEncrypting_ThenDataIsEncrypted()
var input = "Hello, Bouncy Castle!";
var password = "mysecretpassword";
- var encryptedBytes = BlowfishEncryptor.BlowfishEncrypt(input, password, out byte[] iv);
+ var encryptedBytes = BlowfishEncryptor.BlowfishEncrypt(input, password, out _, out _);
var encryptedString = Convert.ToBase64String(encryptedBytes);
@@ -53,9 +53,9 @@ public void GivenSecretData_WhenBlowfishEncrypting_ThenDataCanBeDecrypted()
var input = "Hello, Bouncy Castle!";
var password = "mysecretpassword";
- var encryptedBytes = BlowfishEncryptor.BlowfishEncrypt(input, password, out byte[] iv);
+ var encryptedBytes = BlowfishEncryptor.BlowfishEncrypt(input, password, out byte[] salt, out byte[] iv);
- var myDecryptedStr = BlowfishEncryptor.BlowfishDecrypt(encryptedBytes, password, iv);
+ var myDecryptedStr = BlowfishEncryptor.BlowfishDecrypt(encryptedBytes, password, salt, iv);
Assert.IsNotNull(myDecryptedStr);
Assert.AreEqual(input, myDecryptedStr);