static byte[] MFcrypt(byte[] P, byte[] S, int cost, int blockSize, int parallel, int?maxThreads) { int MFLen = blockSize * 128; if (maxThreads == null) { maxThreads = int.MaxValue; } if (!BitMath.IsPositivePowerOf2(cost)) { throw Exceptions.ArgumentOutOfRange("cost", "Cost must be a positive power of 2."); } Check.Range("blockSize", blockSize, 1, int.MaxValue / 128); Check.Range("parallel", parallel, 1, int.MaxValue / MFLen); Check.Range("maxThreads", (int)maxThreads, 1, int.MaxValue); byte[] B = Pbkdf2.ComputeDerivedKey(new HMACSHA256(P), S, 1, parallel * MFLen); uint[] B0 = new uint[B.Length / 4]; for (int i = 0; i < B0.Length; i++) { B0[i] = BitPacking.UInt32FromLEBytes(B, i * 4); } // code is easier with uint[] ThreadSMixCalls(B0, MFLen, cost, blockSize, parallel, (int)maxThreads); for (int i = 0; i < B0.Length; i++) { BitPacking.LEBytesFromUInt32(B0[i], B, i * 4); } Security.Clear(B0); return(B); }
/// <inheritdoc /> public override long Seek(long offset, SeekOrigin origin) { long pos; switch (origin) { case SeekOrigin.Begin: pos = offset; break; case SeekOrigin.Current: pos = Position + offset; break; case SeekOrigin.End: pos = Length + offset; break; default: throw Exceptions.ArgumentOutOfRange("origin", "Unknown seek type."); } if (pos < 0) { throw Exceptions.Argument("offset", "Can't seek before the stream start."); } Position = pos; return(pos); }
/// <inheritdoc /> public override string GenerateSalt(CrypterOptions options) { Check.Null("options", options); int rounds = options.GetValue(CrypterOption.Rounds, 6); Check.Range("CrypterOption.Rounds", rounds, MinRounds, MaxRounds); string prefix; switch (options.GetValue(CrypterOption.Variant, BlowfishCrypterVariant.Unspecified)) { case BlowfishCrypterVariant.Unspecified: prefix = "$2a$"; break; case BlowfishCrypterVariant.Compatible: prefix = "$2x$"; break; case BlowfishCrypterVariant.Corrected: prefix = "$2y$"; break; default: throw Exceptions.ArgumentOutOfRange("CrypterOption.Variant", "Unknown variant."); } return(prefix + rounds.ToString("00") + '$' + Base64Encoding.Blowfish.GetString(Security.GenerateRandomBytes(16))); }
/// <inheritdoc /> public override string GenerateSalt(CrypterOptions options) { Check.Null("options", options); switch (options.GetValue(CrypterOption.Variant, LdapCrypterVariant.SSha)) { case LdapCrypterVariant.Crypt: Crypter crypter = options.GetValue <Crypter>(LdapCrypterOption.Crypter); if (crypter == null) { throw Exceptions.Argument("LdapCrypterOption.Crypter", "Crypter not set. Did you intend Crypter.TraditionalDes (the slappasswd default)?"); } CrypterOptions crypterOptions = options.GetValue(LdapCrypterOption.CrypterOptions, CrypterOptions.None); return("{CRYPT}" + crypter.GenerateSalt(crypterOptions)); case LdapCrypterVariant.SSha: return("{SSHA}" + Convert.ToBase64String(Security.GenerateRandomBytes(8))); case LdapCrypterVariant.SMD5: return("{SMD5}" + Convert.ToBase64String(Security.GenerateRandomBytes(8))); case LdapCrypterVariant.Sha: return("{SHA}"); case LdapCrypterVariant.MD5: return("{MD5}"); case LdapCrypterVariant.Cleartext: return("{CLEARTEXT}"); default: throw Exceptions.ArgumentOutOfRange("CrypterOption.Variant", "Unknown variant."); } }
/// <inheritdoc /> public override string GenerateSalt(CrypterOptions options) { Check.Null("options", options); int rounds = options.GetValue(CrypterOption.Rounds, 14); Check.Range("CrypterOption.Rounds", rounds, MinRounds, MaxRounds); string prefix; switch (options.GetValue(CrypterOption.Variant, PhpassCrypterVariant.Standard)) { case PhpassCrypterVariant.Standard: prefix = "$P$"; break; case PhpassCrypterVariant.Phpbb: prefix = "$H$"; break; case PhpassCrypterVariant.Drupal: prefix = "$S$"; break; default: throw Exceptions.ArgumentOutOfRange("CrypterOption.Variant", "Unknown variant."); } return(prefix + Base64Encoding.UnixMD5.GetChar(rounds) + Base64Encoding.UnixMD5.GetString(Security.GenerateRandomBytes(6))); }
/// <inheritdoc /> public override string Crypt(byte[] password, string salt) { Check.Null("password", password); Check.Null("salt", salt); Match match = _regex.Match(salt); if (!match.Success) { throw Exceptions.Argument("salt", "Invalid salt."); } byte[] saltBytes = null, crypt = null; try { string roundsString = match.Groups["rounds"].Value; int rounds = Base64Encoding.UnixMD5.GetValue(roundsString[0]); if (rounds < MinRounds || rounds > MaxRounds) { throw Exceptions.ArgumentOutOfRange("salt", "Invalid number of rounds."); } string prefixString = match.Groups["prefix"].Value; bool sha512 = prefixString == "$S$"; string saltString = match.Groups["salt"].Value; saltBytes = Encoding.ASCII.GetBytes(saltString); HashAlgorithm A; if (sha512) { A = System.Security.Cryptography.SHA512.Create(); } else { A = System.Security.Cryptography.MD5.Create(); } crypt = Crypt(password, saltBytes, rounds, A); string hashString = Base64Encoding.UnixMD5.GetString(crypt); if (sha512) { hashString = hashString.Substring(0, 43); } string result = prefixString + roundsString + saltString + hashString; return(result); } finally { Security.Clear(saltBytes); Security.Clear(crypt); } }
public TElement this[int index] { get { if (index < 0 || index >= mElements.Count) { throw Exceptions.ArgumentOutOfRange(Parameter.Index); } return(mElements[index]); } set { throw Exceptions.NotSupported(); } }
static byte[] MFcrypt(byte[] P, byte[] S, int cost, int blockSize, int parallel, int?maxThreads) { int MFLen = blockSize * 128; if (maxThreads == null) { maxThreads = int.MaxValue; } if (!BitMath.IsPositivePowerOf2(cost)) { throw Exceptions.ArgumentOutOfRange("cost", "Cost must be a positive power of 2."); } Check.Range("blockSize", blockSize, 1, int.MaxValue / 128); Check.Range("parallel", parallel, 1, int.MaxValue / MFLen); Check.Range("maxThreads", (int)maxThreads, 1, int.MaxValue); #if NO_NATIVE_HMACSHA512 var mac = new NBitcoin.BouncyCastle.Crypto.Macs.HMac(new NBitcoin.BouncyCastle.Crypto.Digests.Sha256Digest()); mac.Init(new KeyParameter(P)); byte[] B = Pbkdf2.ComputeDerivedKey(mac, S, 1, parallel * MFLen); #elif NO_NATIVE_RFC2898_HMACSHA512 byte[] B = Pbkdf2.ComputeDerivedKey(new HMACSHA256(P), S, 1, parallel * MFLen); #else byte[] B = null; if (S.Length >= 8) { // While we should be able to use Rfc2898DeriveBytes if salt is less than 8 bytes, it sadly does not accept salt less than 8 bytes needed for BIP38 using System.Security.Cryptography.Rfc2898DeriveBytes derive = new System.Security.Cryptography.Rfc2898DeriveBytes(P, S, 1, System.Security.Cryptography.HashAlgorithmName.SHA256); B = derive.GetBytes(parallel * MFLen); } else { B = Pbkdf2.ComputeDerivedKey(new HMACSHA256(P), S, 1, parallel * MFLen); } #endif uint[] B0 = new uint[B.Length / 4]; for (int i = 0; i < B0.Length; i++) { B0[i] = BitPacking.UInt32FromLEBytes(B, i * 4); } // code is easier with uint[] ThreadSMixCalls(B0, MFLen, cost, blockSize, parallel, (int)maxThreads); for (int i = 0; i < B0.Length; i++) { BitPacking.LEBytesFromUInt32(B0[i], B, i * 4); } Security.Clear(B0); return(B); }
/// <inheritdoc /> public override long Seek(long offset, SeekOrigin origin) { var pos = origin switch { SeekOrigin.Begin => offset, SeekOrigin.Current => Position + offset, SeekOrigin.End => Length + offset, _ => throw Exceptions.ArgumentOutOfRange("origin", "Unknown seek type."), }; if (pos < 0) { throw Exceptions.Argument("offset", "Can't seek before the stream start."); } Position = pos; return(pos); }
/// <inheritdoc /> public override string GenerateSalt(CrypterOptions options) { Check.Null("options", options); string prefix; switch (options.GetValue(CrypterOption.Variant, MD5CrypterVariant.Standard)) { case MD5CrypterVariant.Standard: prefix = "$1$"; break; case MD5CrypterVariant.Apache: prefix = "$apr1$"; break; default: throw Exceptions.ArgumentOutOfRange("CrypterOption.Variant", "Unknown variant."); } return(prefix + Base64Encoding.UnixMD5.GetString(Security.GenerateRandomBytes(6))); }
/// <inheritdoc /> public override string Crypt(byte[] password, string salt) { Check.Null("password", password); Check.Null("salt", salt); Match match = _regex.Match(salt); if (!match.Success) { throw Exceptions.Argument("salt", "Invalid salt."); } byte[] saltBytes = null, formattedKey = null, crypt = null; try { string prefixString = match.Groups["prefix"].Value; bool compatible = prefixString == "$2x$"; int rounds = int.Parse(match.Groups["rounds"].Value); if (rounds < MinRounds || rounds > MaxRounds) { throw Exceptions.ArgumentOutOfRange("salt", "Invalid number of rounds."); } saltBytes = Base64Encoding.Blowfish.GetBytes(match.Groups["salt"].Value); formattedKey = FormatKey(password); crypt = BlowfishCipher.BCrypt(formattedKey, saltBytes, rounds, compatible ? EksBlowfishKeyExpansionFlags.EmulateCryptBlowfishSignExtensionBug : EksBlowfishKeyExpansionFlags.None); string result = string.Format("{0}{1}${2}{3}", prefixString, rounds.ToString("00"), Base64Encoding.Blowfish.GetString(saltBytes), Base64Encoding.Blowfish.GetString(crypt)); return(result); } finally { Security.Clear(saltBytes); Security.Clear(formattedKey); Security.Clear(crypt); } }
static byte[] MFcrypt(byte[] P, byte[] S, int cost, int blockSize, int parallel, int?maxThreads) { int MFLen = blockSize * 128; if (maxThreads == null) { maxThreads = int.MaxValue; } if (!BitMath.IsPositivePowerOf2(cost)) { throw Exceptions.ArgumentOutOfRange("cost", "Cost must be a positive power of 2."); } Check.Range("blockSize", blockSize, 1, int.MaxValue / 128); Check.Range("parallel", parallel, 1, int.MaxValue / MFLen); Check.Range("maxThreads", (int)maxThreads, 1, int.MaxValue); #if !(USEBC || NETSTANDARD1X) byte[] B = Pbkdf2.ComputeDerivedKey(new HMACSHA256(P), S, 1, parallel * MFLen); #else var mac = new NBitcoin.BouncyCastle.Crypto.Macs.HMac(new NBitcoin.BouncyCastle.Crypto.Digests.Sha256Digest()); mac.Init(new KeyParameter(P)); byte[] B = Pbkdf2.ComputeDerivedKey(mac, S, 1, parallel * MFLen); #endif uint[] B0 = new uint[B.Length / 4]; for (int i = 0; i < B0.Length; i++) { B0[i] = BitPacking.UInt32FromLEBytes(B, i * 4); } // code is easier with uint[] ThreadSMixCalls(B0, MFLen, cost, blockSize, parallel, (int)maxThreads); for (int i = 0; i < B0.Length; i++) { BitPacking.LEBytesFromUInt32(B0[i], B, i * 4); } Security.Clear(B0); return(B); }
/// <inheritdoc /> public override string Crypt(byte[] password, string salt) { Check.Null("password", password); Check.Null("salt", salt); Match match; LdapCrypterVariant variant; if (!TryMatch(salt, out match, out variant)) { throw Exceptions.Argument("salt", "Invalid salt."); } string prefixString = match.Groups["prefix"].Value; string saltString = match.Groups["salt"].Value; switch (variant) { case LdapCrypterVariant.Crypt: Crypter crypter; if (!_environment.TryGetCrypter(saltString, out crypter)) { goto default; } if (crypter is LdapCrypter) { throw Exceptions.Argument("salt", "LDAP {CRYPT} tried to use an LDAP scheme."); } return(prefixString + crypter.Crypt(password, saltString)); case LdapCrypterVariant.SSha512: return(prefixString + SaltedCrypt(SHA512.Create(), password, saltString)); case LdapCrypterVariant.SSha384: return(prefixString + SaltedCrypt(SHA384.Create(), password, saltString)); case LdapCrypterVariant.SSha256: return(prefixString + SaltedCrypt(SHA256.Create(), password, saltString)); case LdapCrypterVariant.SSha: return(prefixString + SaltedCrypt(SHA1.Create(), password, saltString)); case LdapCrypterVariant.SMD5: return(prefixString + SaltedCrypt(System.Security.Cryptography.MD5.Create(), password, saltString)); case LdapCrypterVariant.Sha512: return(prefixString + UnsaltedCrypt(SHA512.Create(), password)); case LdapCrypterVariant.Sha384: return(prefixString + UnsaltedCrypt(SHA384.Create(), password)); case LdapCrypterVariant.Sha256: return(prefixString + UnsaltedCrypt(SHA256.Create(), password)); case LdapCrypterVariant.Sha: return(prefixString + UnsaltedCrypt(SHA1.Create(), password)); case LdapCrypterVariant.MD5: return(prefixString + UnsaltedCrypt(System.Security.Cryptography.MD5.Create(), password)); case LdapCrypterVariant.Cleartext: return(prefixString + Encoding.UTF8.GetString(password)); default: throw Exceptions.ArgumentOutOfRange("CrypterOption.Variant", "Unknown variant."); } }