/// <summary>
 ///     Create a hashed representation of the plain text.
 /// </summary>
 /// <param name="plainText">The text to hash</param>
 /// <param name="supportedHashAlgorithm">If supplied the algorithm to hash the plain text with. Otherwise default.</param>
 /// <param name="complexityThrottle">
 ///     Offers the ability to tune the algorithm in order to increase the complexity. 1 being
 ///     the lowest value and 100 being very large.
 /// </param>
 /// <param name="saltProvider">Provider of the salt used for creating the hash.</param>
 private HashedValue(string plainText, SupportedHashAlgorithm supportedHashAlgorithm, int complexityThrottle, ICryptoProvider saltProvider)
 {
     _algorithm          = supportedHashAlgorithm;
     _complexityThrottle = complexityThrottle;
     _saltProvider       = saltProvider;
     ComputeHashWorker(plainText, supportedHashAlgorithm, complexityThrottle);
 }
        /// <summary>
        /// Builds a SHA256 hash of the data contained in this <see cref="AuditEntry"/>.
        /// </summary>
        /// <param name="hashAlgorithm"><see cref="SupportedHashAlgorithm"/> to use for hashing data.</param>
        /// <returns>Hash byte array.</returns>
        private byte[] HashMessage(SupportedHashAlgorithm hashAlgorithm)
        {
            HashAlgorithm hasher = null;

            switch (hashAlgorithm)
            {
            case SupportedHashAlgorithm.SHA1:
                hasher = new SHA1Managed();
                break;

            case SupportedHashAlgorithm.SHA256:
                hasher = new SHA256Managed();
                break;

            case SupportedHashAlgorithm.SHA384:
                hasher = new SHA384Managed();
                break;

            case SupportedHashAlgorithm.SHA512:
                hasher = new SHA512Managed();
                break;
            }

            var endoding = new UnicodeEncoding();

            var id        = BitConverter.GetBytes(Sequence);
            var createdAt = BitConverter.GetBytes(CreatedAt.ToBinary());
            var strData   = endoding.GetBytes($"{Stream}{Action}{UserDetails}{DataPayload}");

            return(hasher.ComputeHash(id.Concat(createdAt).Concat(strData).ToArray()));
        }
        /// <summary>
        /// Uses the provided <see cref="RSACryptoServiceProvider"/> to verify the <see cref="Signature"/>
        /// for this <see cref="AuditEntry"/>.
        /// </summary>
        /// <param name="csp"><see cref="RSACryptoServiceProvider"/> that contains a public key to verify this <see cref="AuditEntry"/> with.</param>
        /// <param name="hashAlgorithm"><see cref="SupportedHashAlgorithm"/> to use for verifying signature.</param>
        /// <returns>True if the signature is valid, false otherwise.</returns>
        public bool VerifyAuditMessage(RSACryptoServiceProvider csp, SupportedHashAlgorithm hashAlgorithm)
        {
            var hash = HashMessage(hashAlgorithm);

            Hash = Convert.ToBase64String(hash);
            return(csp.VerifyHash(hash, CryptoConfig.MapNameToOID(hashAlgorithm.ToString()), Convert.FromBase64String(Signature)));
        }
예제 #4
0
 public GUIRow(SupportedHashAlgorithm hashAlgorithm, CheckBox checkBox, TextBox textBox, Button copyButton, ProgressBar progressBar, Image hashCheckImage)
 {
     this.hashAlgorithm  = hashAlgorithm;
     this.CheckBox       = checkBox;
     this.TextBox        = textBox;
     this.CopyButton     = copyButton;
     this.progressBar    = progressBar;
     this.HashCheckImage = hashCheckImage;
 }
예제 #5
0
        public static string Hash(string plainText, SupportedHashAlgorithm hashAlgorithm, bool addSalt = true)
        {
            // Define min and max salt sizes.
            const int MinSaltSize = 4;
            const int MaxSaltSize = 8;

            return(Hash(
                       plainText,
                       hashAlgorithm,
                       addSalt ?
                       GenerateCryptographicallyRandomBytes(Tools.Maths.RandomNumberGenerator.Next(MinSaltSize, MaxSaltSize)) :
                       null
                       ));
        }
        /// <summary>
        /// Uses the provided <see cref="RSACryptoServiceProvider"/> to sign this <see cref="AuditEntry"/>.
        /// </summary>
        /// <param name="csp"><see cref="RSACryptoServiceProvider"/> that contains a private key to sign this <see cref="AuditEntry"/> with.</param>
        /// <param name="hashAlgorithm"><see cref="SupportedHashAlgorithm"/> to use for signing data.</param>
        public void SignAuditMesssage(RSACryptoServiceProvider csp, SupportedHashAlgorithm hashAlgorithm)
        {
            if (Signature != null)
            {
                throw new InvalidOperationException("Signature already set!");
            }

            var hash      = HashMessage(hashAlgorithm);
            var algorithm = CryptoConfig.MapNameToOID(hashAlgorithm.ToString());
            var signature = csp.SignHash(hash, algorithm);

            Hash      = Convert.ToBase64String(hash);
            Signature = Convert.ToBase64String(signature);
        }
예제 #7
0
        /// <summary>
        /// The overridden PrepareForExecute method.
        /// </summary>
        public override void PrepareForExecute()
        {
            // Assign internal variables.

            // Create a string builder to be used later.
            _stringBuilder = new StringBuilder();

            // Create a hash algorithm based on the value in the hash algorithm
            // component property.
            SupportedHashAlgorithm selectedHashAlgorithm = (SupportedHashAlgorithm)ComponentMetaData.CustomPropertyCollection[_hashAlgorithmPropertyName].Value;
            String selectedHashAlgorithmName             = selectedHashAlgorithm.ToString();

            _hashAlgorithm = HashAlgorithm.Create(selectedHashAlgorithmName);

            base.PrepareForExecute();
        }
예제 #8
0
        /// <summary>
        /// The overridden Validate method.
        /// </summary>
        /// <returns></returns>
        public override DTSValidationStatus Validate()
        {
            Boolean pbCancel;

            // Only one input is allowed.
            if (ComponentMetaData.InputCollection.Count > 1)
            {
                ComponentMetaData.FireError(0, ComponentMetaData.Name, _errorTooManyInputs, null, 0, out pbCancel);
                return(DTSValidationStatus.VS_ISBROKEN);
            }

            // At least one input column must be selected.
            if (ComponentMetaData.InputCollection[0].InputColumnCollection.Count < 1)
            {
                ComponentMetaData.FireError(0, ComponentMetaData.Name, _errorNoInputColumns, null, 0, out pbCancel);
                return(DTSValidationStatus.VS_ISBROKEN);
            }

            // A valid hash Algorithm must be selected.
            SupportedHashAlgorithm selectedHashAlgorithm = (SupportedHashAlgorithm)ComponentMetaData.CustomPropertyCollection[_hashAlgorithmPropertyName].Value;

            if (String.IsNullOrEmpty(selectedHashAlgorithm.ToString()))
            {
                ComponentMetaData.FireError(0, ComponentMetaData.Name, _errorNoHashAlgorithm, null, 0, out pbCancel);
                return(DTSValidationStatus.VS_ISBROKEN);
            }

            // The built-in check sum column must not be missing.
            IDTSOutput100 _output = ComponentMetaData.OutputCollection[0];
            List <IDTSOutputColumn100> outputColumnList = new List <IDTSOutputColumn100>();

            outputColumnList.AddRange
            (
                _output.OutputColumnCollection.Cast <IDTSOutputColumn100>()
            );
            if (!outputColumnList.Exists(outputColumn => outputColumn.Name == _checkSumColumnName))
            {
                ComponentMetaData.FireError(0, ComponentMetaData.Name, _errorMissingChecksumColumn, null, 0, out pbCancel);
                return(DTSValidationStatus.VS_ISCORRUPT);
            }

            return(base.Validate());
        }
예제 #9
0
        /// <summary>
        /// Generates a hash for the given plain text value and returns a
        /// base64-encoded result. Before the hash is computed, a random salt
        /// is generated and appended to the plain text. This salt is stored at
        /// the end of the hash value, so it can be used later for hash
        /// verification.
        /// </summary>
        /// <param name="plainText">
        /// Plaintext value to be hashed. The function does not check whether
        /// this parameter is null.
        /// </param>
        /// <param name="hashAlgorithm">
        /// The hash algorithm to use.
        /// </param>
        /// <param name="saltBytes">
        /// Salt bytes.
        /// </param>
        /// <returns>
        /// Hash value formatted as a base64-encoded string.
        /// </returns>
        public static string Hash(string plainText, SupportedHashAlgorithm hashAlgorithm, byte[] saltBytes)
        {
            if (saltBytes == null)
            {
                saltBytes = new byte[0];
            }

            // Convert plain text into a byte array.
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

            // Allocate array, which will hold plain text and salt.
            byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];

            // Copy plain text bytes into resulting array.
            for (int i = 0; i < plainTextBytes.Length; i++)
            {
                plainTextWithSaltBytes[i] = plainTextBytes[i];
            }

            // Append salt bytes to the resulting array.
            for (int i = 0; i < saltBytes.Length; i++)
            {
                plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
            }

            // Because we support multiple hashing algorithms, we must define
            // hash object as a common (abstract) base class. We will specify the
            // actual hashing algorithm class later during object creation.
            HashAlgorithm hash;


            // Initialize appropriate hashing algorithm class.
            switch (hashAlgorithm)
            {
            case SupportedHashAlgorithm.SHA1:
                hash = new SHA1Managed();
                break;

            case SupportedHashAlgorithm.SHA256:
                hash = new SHA256Managed();
                break;

#if !__WP8__
            case SupportedHashAlgorithm.SHA384:
                hash = new SHA384Managed();
                break;

            case SupportedHashAlgorithm.SHA512:
                hash = new SHA512Managed();
                break;

            case SupportedHashAlgorithm.MD5:
                hash = new MD5CryptoServiceProvider();
                break;
#endif
            default:
                throw new SoftwareException("Failed to compute hash. Requested an unsupported hash algorithm '{0}'", hashAlgorithm);
            }

            // Compute hash value of our plain text with appended salt.
            byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

            // Create array which will hold hash and original salt bytes.
            byte[] hashWithSaltBytes = new byte[hashBytes.Length +
                                                saltBytes.Length];

            // Copy hash bytes into resulting array.
            for (int i = 0; i < hashBytes.Length; i++)
            {
                hashWithSaltBytes[i] = hashBytes[i];
            }

            // Append salt bytes to the result.
            for (int i = 0; i < saltBytes.Length; i++)
            {
                hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
            }

            // Convert result into a base64-encoded string.
            string hashValue = Convert.ToBase64String(hashWithSaltBytes);

            // Return the result.
            return(hashValue);
        }
 /// <summary>
 ///     Creates a hashed representation of the plain text.
 ///     This constructor uses the salt from the <see cref="oldHashedValue" /> in order to make comparison between
 ///     hashed values easier. This should be used with caution and is only recommended in instances such as
 ///     keeping a password history where you want to see if a password has been used before. If the hash has to
 ///     be calculated for each password in the history this could take a large amount of time.
 /// </summary>
 /// <param name="plainText">The text to hash</param>
 /// <param name="oldHashedValue">A hashed value in which to re-use the salt from.</param>
 /// <param name="saltProvider">Provider of the salt used for creating the hash.</param>
 private HashedValue(string plainText, HashedValue oldHashedValue)
 {
     _algorithm          = oldHashedValue.Algorithm;
     _complexityThrottle = oldHashedValue.ComplexityThrottle;
     ComputeHashWorker(plainText, _algorithm, _complexityThrottle, oldHashedValue.SaltBytes);
 }
 public IHashedValue CreateHash(string text, SupportedHashAlgorithm algorithm, int hashComplexity)
 {
     return(new HashedValue(text, algorithm, hashComplexity, _cryptoProvider));
 }
예제 #12
0
        public static IAuditTrailHubBuilder AddMongoDBMerkleTree(this IAuditTrailHubBuilder builder, SupportedHashAlgorithm hashAlgorithm, ECParameters signatureParameters)
        {
            Sha2 sha = hashAlgorithm switch
            {
                SupportedHashAlgorithm.Sha256 => Sha256.Shared,
                SupportedHashAlgorithm.Sha384 => Sha384.Shared,
                SupportedHashAlgorithm.Sha512 => Sha512.Shared,
                _ => Sha256.Shared
            };

            builder.Services.TryAddSingleton <IMerkleHasher>(new MerkleHasher(sha));
            builder.Services.TryAddSingleton <IMerkleSigner>(new ECDsaMerkleSigner(signatureParameters));
            builder.Services.Replace(new ServiceDescriptor(typeof(IMerkleTree), typeof(MongoDBMerkleTree), ServiceLifetime.Singleton));

            return(builder);
        }
    }
예제 #13
0
 public Hash(SupportedHashAlgorithm hashAlgorithm, bool?hmac)
 {
     this.HashAlgorithm = hashAlgorithm;
     this.Hmac          = hmac;
 }
예제 #14
0
        /// <summary>
        /// Compares a hash of the specified plain text value to a given hash
        /// value. Plain text is hashed with the same salt value as the original
        /// hash.
        /// </summary>
        /// <param name="plainText">
        /// Plain text to be verified against the specified hash. The function
        /// does not check whether this parameter is null.
        /// </param>
        /// <param name="hashAlgorithm">
        /// Name of the hash algorithm. Allowed values are: "MD5", "SHA1",
        /// "SHA256", "SHA384", and "SHA512" (if any other value is specified,
        /// MD5 hashing algorithm will be used). This value is case-insensitive.
        /// </param>
        /// <param name="hashValue">
        /// Base64-encoded hash value produced by ComputeHash function. This value
        /// includes the original salt appended to it.
        /// </param>
        /// <returns>
        /// If computed hash mathes the specified hash the function the return
        /// value is true; otherwise, the function returns false.
        /// </returns>
        /// <remarks>The salt is retrieved by getting the excess bytes off the end of the hashValue, since each hash algorithm provides fixed length hash.</remarks>
        public static bool VerifyHash(string plainText, SupportedHashAlgorithm hashAlgorithm, string hashValue)
        {
            // Convert base64-encoded hash value into a byte array.
            byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue);

            // We must know size of hash (without salt).
            int hashSizeInBits, hashSizeInBytes;

            // Size of hash is based on the specified algorithm.
            switch (hashAlgorithm)
            {
            case SupportedHashAlgorithm.SHA1:
                hashSizeInBits = 160;
                break;

            case SupportedHashAlgorithm.SHA256:
                hashSizeInBits = 256;
                break;

#if !__WP8__
            case SupportedHashAlgorithm.SHA384:
                hashSizeInBits = 384;
                break;

            case SupportedHashAlgorithm.SHA512:
                hashSizeInBits = 512;
                break;

            case SupportedHashAlgorithm.MD5:
                hashSizeInBits = 128;
                break;
#endif
            default:
                throw new SoftwareException("Failed to verify hash. Requested an unsupported hash algorithm '{0}'", hashAlgorithm);
                break;
            }

            // Convert size of hash from bits to bytes.
            hashSizeInBytes = hashSizeInBits / 8;

            // Make sure that the specified hash value is long enough.
            if (hashWithSaltBytes.Length < hashSizeInBytes)
            {
                return(false);
            }

            // Allocate array to hold original salt bytes retrieved from hash.
            byte[] saltBytes = new byte[hashWithSaltBytes.Length -
                                        hashSizeInBytes];

            // Copy salt from the end of the hash to the new array.
            for (int i = 0; i < saltBytes.Length; i++)
            {
                saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];
            }

            // Compute a new hash string.
            string expectedHashString = Hash(plainText, hashAlgorithm, saltBytes);

            // If the computed hash matches the specified hash,
            // the plain text value must be correct.
            return(hashValue == expectedHashString);
        }
        private void Init()
        {
            if (_inited)
            {
                return;
            }

            _algorithm = DetermineHashTypeFromHash(HashString);

            byte[] hashWithSaltBytes = Convert.FromBase64String(HashString);
            int    hashSizeInBits;
            bool   hasIterationsCount = false;

            switch (_algorithm)
            {
            case SupportedHashAlgorithm.SHA1:
                hashSizeInBits = 160;
                break;

            case SupportedHashAlgorithm.SHA256:
                hashSizeInBits = 256;
                break;

            case SupportedHashAlgorithm.SHA384:
                hashSizeInBits = 384;
                break;

            case SupportedHashAlgorithm.SHA512:
                hashSizeInBits = 512;
                break;

            case SupportedHashAlgorithm.PBKDF2:
                hashSizeInBits     = 192;
                hasIterationsCount = true;
                break;

            default:
                hashSizeInBits = 128;
                break;
            }

            var hashSizeInBytes           = hashSizeInBits / 8;
            var iterationCountSizeInBytes = hasIterationsCount ? 4 : 0;
            var algoMarkerSizeInBytes     = _algorithm != SupportedHashAlgorithm.MD5 ? 6 : 0;

            if (hashWithSaltBytes.Length < (hashSizeInBytes + iterationCountSizeInBytes))
            {
                throw new FormatException("Hash value should have salt but doesnt.");
            }

            _saltBytes =
                new byte[
                    hashWithSaltBytes.Length - (hashSizeInBytes + iterationCountSizeInBytes + algoMarkerSizeInBytes)];
            for (int i = 0; i < _saltBytes.Length; i++)
            {
                _saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];
            }

            var iterationBytes = new byte[iterationCountSizeInBytes];

            for (int i = 0; i < iterationBytes.Length; i++)
            {
                iterationBytes[i] = hashWithSaltBytes[hashSizeInBytes + _saltBytes.Length + i];
            }

            _complexityThrottle = hasIterationsCount ? BitConverter.ToInt32(iterationBytes, 0) : 1;

            _inited = true;
        }
예제 #16
0
        /// <summary>
        /// Method for generating password from input values.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="login"></param>
        /// <param name="passphrase"></param>
        /// <param name="algorithm"></param>
        /// <param name="characterSet"></param>
        /// <param name="maxPwLength"></param>
        /// <returns>Generated password</returns>
        public static string GeneratePassword(string host, string login,
            string passphrase, SupportedHashAlgorithm algorithm, string characterSet,
            int maxPwLength)
        {
            var hashAlgorithm = CryptoConfig.CreateFromName(algorithm.ToString()) as HashAlgorithm;

            string basestring;
            if (login.Length == 0)
            {
                basestring = passphrase + "@" + host;
            }
            else
            {
                basestring = login + "@" + host + "#" + passphrase;
            }
            byte[] digest = CreateHash(hashAlgorithm, basestring);

            int digestLength = digest.Length;
            string sPassword = "";

            int pos = 0;
            int bitno = 0;
            int charSetLength = characterSet.Length;

            int maxBitCnt = (int)Math.Ceiling(Math.Log(charSetLength) / Math.Log(2));

            for (int i = 0; (i < maxPwLength) && ((pos * 8 + bitno) < (digestLength * 8)); ++i)
            {
                int part = 0;
                int bitCnt = maxBitCnt;
                int actPos = pos;
                int actBitno = bitno;

                for (int j = 0; (j < bitCnt) && ((actPos * 8 + actBitno) < (digestLength * 8)); ++j)
                {
                    part <<= 1;
                    part |= ((digest[actPos] & (1 << actBitno)) != 0) ? 1 : 0;
                    if (++actBitno >= 8)
                    {
                        ++actPos;
                        actBitno = 0;
                    }
                }

                if (part >= charSetLength)
                {
                    part >>= 1;
                    --actBitno;
                    if (actBitno < 0)
                    {
                        --actPos;
                        actBitno = 7;
                    }
                }

                bitno = actBitno;
                pos = actPos;

                sPassword = sPassword + characterSet[part];
            }

            return sPassword;
        }
        private void ComputeHashWorker(string plainText, SupportedHashAlgorithm algorithm, int complexityThrottle = 1,
                                       byte[] saltBytes = null)
        {
            if (saltBytes == null)
            {
                saltBytes = _saltProvider.GetNonZeroBytes(SALT_BYTE_LENGTH);
            }

            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            var algoBytes      = Encoding.UTF8.GetBytes(GetAlgoIdentifier(algorithm));

            byte[] hashBytes;
            var    hasComplexityThrottle = false;

            _complexityThrottle = complexityThrottle;

            switch (algorithm)
            {
            case SupportedHashAlgorithm.SHA1:
                hashBytes = CryptoHashAlgorithmComputeBytes(plainTextBytes, saltBytes, new SHA1Managed());
                break;

            case SupportedHashAlgorithm.SHA256:
                hashBytes = CryptoHashAlgorithmComputeBytes(plainTextBytes, saltBytes, new SHA256Managed());
                break;

            case SupportedHashAlgorithm.SHA384:
                hashBytes = CryptoHashAlgorithmComputeBytes(plainTextBytes, saltBytes, new SHA384Managed());
                break;

            case SupportedHashAlgorithm.SHA512:
                hashBytes = CryptoHashAlgorithmComputeBytes(plainTextBytes, saltBytes, new SHA512Managed());
                break;

            case SupportedHashAlgorithm.PBKDF2:
                complexityThrottle = complexityThrottle * 1000;

                hashBytes             = new Rfc2898DeriveBytes(plainTextBytes, saltBytes, complexityThrottle).GetBytes(24);
                hasComplexityThrottle = true;
                break;

            default:
                hashBytes = CryptoHashAlgorithmComputeBytes(plainTextBytes, saltBytes,
                                                            new MD5CryptoServiceProvider());
                break;
            }

            _saltBytes = saltBytes;

            if (hasComplexityThrottle)
            {
                saltBytes = saltBytes.Concat(BitConverter.GetBytes(_complexityThrottle)).ToArray();
            }

            saltBytes = saltBytes.Concat(algoBytes).ToArray();

            // append the salt bytes to the end of the hash
            IEnumerable <byte> hashWithSaltBytes = hashBytes.Concat(saltBytes);

            HashString = Convert.ToBase64String(hashWithSaltBytes.ToArray());

            _inited = true;
        }
예제 #18
0
        /// <summary>
        /// Method for generating password from input values.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="login"></param>
        /// <param name="passphrase"></param>
        /// <param name="algorithm"></param>
        /// <param name="characterSet"></param>
        /// <param name="maxPwLength"></param>
        /// <returns>Generated password</returns>
        public static string GeneratePassword(string host, string login, string passphrase, SupportedHashAlgorithm algorithm, string characterSet, int maxPwLength)
        {
            var hashAlgorithm = CryptoConfig.CreateFromName(algorithm.ToString()) as HashAlgorithm;

            var basestring = string.IsNullOrWhiteSpace(login) ? $"{passphrase}@{host}" : $"{login}@{host}#{passphrase}";
            var digest     = CreateHash(hashAlgorithm, basestring);

            var digestLength = digest.Length;
            var sPassword    = string.Empty;

            var pos           = 0;
            var bitno         = 0;
            var charSetLength = characterSet.Length;

            var maxBitCnt = (int)Math.Ceiling(Math.Log(charSetLength) / Math.Log(2));

            for (var i = 0; (i < maxPwLength) && (pos * 8 + bitno < digestLength * 8); ++i)
            {
                var part     = 0;
                var bitCnt   = maxBitCnt;
                var actPos   = pos;
                var actBitno = bitno;

                for (var j = 0; (j < bitCnt) && (actPos * 8 + actBitno < digestLength * 8); ++j)
                {
                    part <<= 1;
                    part  |= (digest[actPos] & (1 << actBitno)) != 0 ? 1 : 0;
                    if (++actBitno >= 8)
                    {
                        ++actPos;
                        actBitno = 0;
                    }
                }

                if (part >= charSetLength)
                {
                    part >>= 1;
                    --actBitno;
                    if (actBitno < 0)
                    {
                        --actPos;
                        actBitno = 7;
                    }
                }

                bitno = actBitno;
                pos   = actPos;

                sPassword = sPassword + characterSet[part];
            }

            return(sPassword);
        }
        public void When_hashing_Then_works(string toHash, string expected, SupportedHashAlgorithm algo)
        {
            string actual = CryptographyHelper.Hash.AsString(algo, toHash);

            Assert.That(actual, Is.EqualTo(expected));
        }