diff --git a/.gitignore b/.gitignore
index 5aeb8a5..1fc9b0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ nuget.exe
#*.sln
#*.csproj
#*.kproj
-*.lock.json
\ No newline at end of file
+*.lock.json
+*.vs
diff --git a/src/Scrypt/ScryptEncoder.cs b/src/Scrypt/ScryptEncoder.cs
index aea0094..22fae1e 100644
--- a/src/Scrypt/ScryptEncoder.cs
+++ b/src/Scrypt/ScryptEncoder.cs
@@ -41,7 +41,8 @@ public class ScryptEncoder
///
/// Size of salt in bytes.
///
- private const int SaltLength = 32;
+ public static readonly int SaltLength = 32;
+
private const int DefaultIterationCount = 16384;
private const int DefaultBlockSize = 8;
private const int DefaultThreadCount = 1;
@@ -49,10 +50,13 @@ public class ScryptEncoder
private readonly int _iterationCount;
private readonly int _blockSize;
private readonly int _threadCount;
+ private readonly byte[] _salt;
private readonly RandomNumberGenerator _saltGenerator;
#endregion
+
+
#region Constructors
///
@@ -94,6 +98,7 @@ public ScryptEncoder(int iterationCount, int blockSize, int threadCount, RandomN
_iterationCount = iterationCount;
_blockSize = blockSize;
_threadCount = threadCount;
+ _salt = new byte[SaltLength];
_saltGenerator = saltGenerator;
}
@@ -147,11 +152,9 @@ public string Encode(string password)
throw new ArgumentNullException("password");
}
- var saltBytes = new byte[SaltLength];
+ _saltGenerator.GetBytes(_salt);
- _saltGenerator.GetBytes(saltBytes);
-
- return EncodeV2(password, saltBytes, _iterationCount, _blockSize, _threadCount);
+ return EncodeV2(password, _salt, _iterationCount, _blockSize, _threadCount);
}
///
@@ -196,6 +199,44 @@ public bool IsValid(string hashedPassword)
return true;
}
+ ///
+ /// Hashes a password using the scrypt scheme.
+ ///
+ public static string Encode(int iterationCount, int blockSize, int threadCount, byte[] salt, string password)
+ {
+ if (iterationCount < 1)
+ {
+ throw new ArgumentOutOfRangeException("iterationCount", "IterationCount must be equal or greater than 1.");
+ }
+
+ if (blockSize < 1)
+ {
+ throw new ArgumentOutOfRangeException("blockSize", "BlockSize must be equal or greater than 1.");
+ }
+
+ if (threadCount < 1)
+ {
+ throw new ArgumentOutOfRangeException("threadCount", "ThreadCount must be equal or greater than 1.");
+ }
+
+ if (salt == null)
+ {
+ throw new ArgumentNullException("salt");
+ }
+
+ if (salt.Length != SaltLength)
+ {
+ throw new ArgumentOutOfRangeException("salt", String.Format("Salt length must be equal to {0} bytes.", SaltLength));
+ }
+
+ if (string.IsNullOrEmpty(password))
+ {
+ throw new ArgumentNullException("password");
+ }
+
+ return EncodeV2(password, salt, iterationCount, blockSize, threadCount);
+ }
+
///
/// Hash a password using the scrypt scheme.
///