Exemple #1
0
        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.");
            }
        }
Exemple #5
0
        /// <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)));
        }
Exemple #6
0
        /// <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);
            }
        }
Exemple #7
0
        public TElement this[int index]
        {
            get
            {
                if (index < 0 || index >= mElements.Count)
                {
                    throw Exceptions.ArgumentOutOfRange(Parameter.Index);
                }

                return(mElements[index]);
            }
            set { throw Exceptions.NotSupported(); }
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        /// <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);
            }
        }
Exemple #12
0
        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.");
            }
        }