Пример #1
0
 // Finalize the hash and return the final hash value.
 protected override byte[] HashFinal()
 {
     // Compute the final hash, which is "H(K, H(K, Data))".
     Prepare();
     byte[] inner = alg.InternalHashFinal();
     alg.Initialize();
     if (KeyValue != null)
     {
         alg.InternalHashCore(KeyValue, 0, KeyValue.Length);
     }
     alg.InternalHashCore(inner, 0, inner.Length);
     Array.Clear(inner, 0, inner.Length);
     return(alg.InternalHashFinal());
 }
Пример #2
0
        // Generate a mask using a specific set and byte count.
        //
        // This implementation is based on the description in PKCS #1 v2.1.
        // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
        public override byte[] GenerateMask(byte[] rgbSeed, int cbReturn)
        {
            // Validate the parameters.
            if (rgbSeed == null)
            {
                throw new ArgumentNullException("rgbSeed");
            }
            else if (cbReturn < 0)
            {
                throw new ArgumentOutOfRangeException
                          ("cbReturn", _("ArgRange_NonNegative"));
            }

            // Create the final mask buffer.
            byte[] mask = new byte [cbReturn];

            // Create the hash algorithm instance.
            HashAlgorithm alg = HashAlgorithm.Create(hashName);

            // Create the mask.
            byte[] numbuf = new byte [4];
            byte[] hash;
            int    hashSize = alg.HashSize;
            int    count    = 0;
            int    index    = 0;

            while (index < cbReturn)
            {
                numbuf[0] = (byte)(count >> 24);
                numbuf[1] = (byte)(count >> 16);
                numbuf[2] = (byte)(count >> 8);
                numbuf[3] = (byte)count;
                alg.InternalHashCore(rgbSeed, 0, rgbSeed.Length);
                alg.InternalHashCore(numbuf, 0, 4);
                hash = alg.InternalHashFinal();
                if (hashSize <= (cbReturn - index))
                {
                    Array.Copy(hash, 0, mask, index, hashSize);
                }
                else
                {
                    Array.Copy(hash, 0, mask, index, cbReturn - index);
                }
                Array.Clear(hash, 0, hash.Length);
                alg.Initialize();
                ++count;
                index += hashSize;
            }
            Array.Clear(numbuf, 0, numbuf.Length);

            // The mask has been generated.
            return(null);
        }
Пример #3
0
        // Get the pseudo-random key bytes.
        public override byte[] GetBytes(int cb)
        {
            // Initialize the pseudo-random generator.
            if (hashAlgorithm == null)
            {
                if (strHashName == null)
                {
                    strHashName = "MD5";
                }
                hashAlgorithm = HashAlgorithm.Create(strHashName);
                blockNum      = 1;
                size          = hashAlgorithm.HashSize;
                posn          = size;
            }

            // Allocate the result array and then fill it.
            byte[] result = new byte [cb];
            int    index  = 0;
            int    templen;

            while (cb > 0)
            {
                // Copy existing data from the previous block.
                if (posn < size)
                {
                    templen = (size - posn);
                    if (cb < templen)
                    {
                        templen = cb;
                    }
                    Array.Copy(block, posn, result, index, templen);
                    cb    -= templen;
                    index -= templen;
                    posn   = size;
                    if (cb <= 0)
                    {
                        break;
                    }
                }

                // Generate a new block using the hash algorithm.
                if (strPassword != null)
                {
                    byte[] pwd = Encoding.UTF8.GetBytes(strPassword);
                    hashAlgorithm.InternalHashCore(pwd, 0, pwd.Length);
                    Array.Clear(pwd, 0, pwd.Length);
                }
                if (rgbSalt != null)
                {
                    hashAlgorithm.InternalHashCore
                        (rgbSalt, 0, rgbSalt.Length);
                }
                byte[] numbuf = new byte [4];
                numbuf[0] = (byte)(blockNum >> 24);
                numbuf[1] = (byte)(blockNum >> 16);
                numbuf[2] = (byte)(blockNum >> 8);
                numbuf[3] = (byte)blockNum;
                hashAlgorithm.InternalHashCore(numbuf, 0, 4);
                Array.Clear(numbuf, 0, numbuf.Length);
                byte[] lastHash = hashAlgorithm.InternalHashFinal();
                hashAlgorithm.Initialize();
                templen = iterations;
                byte[] temphash;
                while (templen > 1)
                {
                    hashAlgorithm.InternalHashCore
                        (lastHash, 0, lastHash.Length);
                    temphash = hashAlgorithm.InternalHashFinal();
                    hashAlgorithm.Initialize();
                    for (int tempindex = 0; tempindex < lastHash.Length;
                         ++tempindex)
                    {
                        lastHash[tempindex] ^= temphash[tempindex];
                    }
                    Array.Clear(temphash, 0, temphash.Length);
                    --templen;
                }
                if (block != null)
                {
                    Array.Clear(block, 0, block.Length);
                }
                block = lastHash;
                ++blockNum;
                posn = 0;
            }

            // Return the result array to the caller.
            return(result);
        }