Пример #1
0
        public KdfResult DeriveKey(BitString salt, string password, int c, int keyLen)
        {
            // Could check keyLen, but the allowed max is larger than an int allows, so we just force positive...
            if (keyLen <= 0)
            {
                return(new KdfResult("KeyLen must be greater than 0"));
            }

            var passwordBytes    = Encoding.ASCII.GetBytes(password);
            var iterationsNeeded = keyLen.CeilingDivide(_hmac.OutputLength);
            var saltBytes        = salt.GetPaddedBytes();

            var t   = new byte[GetNextMultiple(keyLen, _hmac.OutputLength) / 8];
            var u   = new byte[_hmac.OutputLength / 8];
            var t_i = new byte[_hmac.OutputLength / 8];

            _hmac.Init(passwordBytes);

            for (var i = 1; i <= iterationsNeeded; i++)
            {
                var iterationCounter = new byte[4];

                iterationCounter[0] = (byte)(i >> 24);
                iterationCounter[1] = (byte)(i >> 16);
                iterationCounter[2] = (byte)(i >> 8);
                iterationCounter[3] = (byte)i;

                //Array.Copy(saltBytes, u, saltBytes.Length);
                //Array.Copy(iterationCounter, 0, u, saltBytes.Length, 4);

                Array.Clear(t_i, 0, t_i.Length);

                for (var j = 1; j <= c; j++)
                {
                    _hmac.FastInit();

                    if (j == 1)
                    {
                        _hmac.Update(saltBytes, salt.BitLength);
                        _hmac.Update(iterationCounter, iterationCounter.Length * 8);
                    }
                    else
                    {
                        _hmac.Update(u, u.Length * 8);
                    }

                    _hmac.Final(ref u);

                    for (var k = 0; k < u.Length; k++)
                    {
                        t_i[k] ^= u[k];
                    }
                }

                Array.Copy(t_i, 0, t, (i - 1) * t_i.Length, t_i.Length);
            }

            return(new KdfResult(new BitString(t).GetMostSignificantBits(keyLen)));
        }
Пример #2
0
        public HashResult HashMessage(BitString message, int outLen = 0)
        {
            var digest = new byte[48];

            Init();
            Update(message.GetPaddedBytes(), message.BitLength);
            Final(digest);

            return(new HashResult(new BitString(digest)));
        }
Пример #3
0
        public MacResult Generate(BitString key, BitString message, int macLength = 0)
        {
            Init(key.GetPaddedBytes());
            Update(message.GetPaddedBytes(), message.BitLength);

            var result = new byte[_processingLen / 8];

            Final(ref result, 0);

            if (macLength == 0 || macLength == OutputLength)
            {
                return(new MacResult(new BitString(result)));
            }

            return(new MacResult(new BitString(result).GetMostSignificantBits(macLength)));
        }
Пример #4
0
        public HashResult HashMessage(BitString message, int outLen = 0)
        {
            if (outLen == 0)
            {
                outLen = _bitLength;
            }

            // If outputBitLength is not a multiple of 8, make it one
            var requestedBitLength = outLen;

            if (outLen % 8 != 0)
            {
                outLen += 8 - (outLen % 8);
            }

            var digest = new byte[outLen / 8];

            Init();
            Update(message.GetPaddedBytes(), message.BitLength);
            Final(digest, outLen);

            return(requestedBitLength == outLen ? new HashResult(new BitString(digest)) : new HashResult(LittleEndianSubstring(new BitString(digest), 0, requestedBitLength)));
        }