Пример #1
0
        /// <summary>
        /// Gets a little endian byte array representation of the version code.
        /// </summary>
        /// <returns>either <c>0x0100</c> for SQL 2000-2008 or <c>0x0200</c> for SQL 2012-SQL 2017</returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <remarks>Originally written because I didn't take endianness into account</remarks>
        public static byte[] GetBytes(this DbaPasswordHashVersion version)
        {
            switch (version)
            {
            case DbaPasswordHashVersion.Sql2000:
                return(new byte[] { 1, 0 });

            case DbaPasswordHashVersion.Sql2012:
                return(new byte[] { 2, 0 });

            default:
                throw new ArgumentOutOfRangeException(nameof(version), version, "Cannot call GetBytes on an invalid password has version.");
            }
        }
Пример #2
0
        public static byte[]  GenerateHash
            (string password, UInt32?salt  = null,
            DbaPasswordHashVersion version = DbaPasswordHashVersion.Sql2016,
            bool caseInsensitive           = false)
        {
            var saltBytes = new byte[4];

            if (salt == null)
            {
                RngCryptoServiceProvider.GetNonZeroBytes(saltBytes);
            }
            else
            {
                saltBytes = BitConverter.GetBytes(salt.Value);
            }
            var passwordBytes = Encoding.Unicode.GetBytes(password).Concat(saltBytes).ToArray();

            byte[] hash;
            switch (version)
            {
            case DbaPasswordHashVersion.Sql2005:
                hash = Sha1.ComputeHash(passwordBytes);
                if (caseInsensitive)
                {
                    var upperCasePasswordBytes = Encoding.Unicode.GetBytes(password.ToUpper()).Concat(saltBytes).ToArray();
                    hash = hash.Concat(Sha1.ComputeHash(upperCasePasswordBytes)).ToArray();
                }
                break;

            case DbaPasswordHashVersion.Sql2012:
                if (caseInsensitive)
                {
                    throw new ArgumentException("Only Sql Server 2000 passwords can be case insensitive.");
                }
                hash = Sha512.ComputeHash(passwordBytes);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(version), $"Unsupported password version of {(uint) version}");
            }
            return(version.GetBytes().Concat(saltBytes).Concat(hash).ToArray());
        }