public BlockAlgorithmKeyWrapTransform(SymmetricAlgorithm symmetricAlgorithm, Salt salt, KeyWrapDirection keyWrapDirection)
        {
            if (symmetricAlgorithm == null)
            {
                throw new ArgumentNullException("symmetricAlgorithm");
            }
            if (salt == null)
            {
                throw new ArgumentNullException("salt");
            }

            if (salt.Length != 0 && salt.Length < symmetricAlgorithm.Key().Length)
            {
                throw new InternalErrorException("Salt is too short. It must be at least as long as the algorithm key, or empty for no salt.");
            }
            _algorithm = symmetricAlgorithm;

            byte[] saltedKey = _algorithm.Key();
            saltedKey.Xor(salt.GetBytes().Reduce(saltedKey.Length));
            _algorithm.SetKey(saltedKey);

            _algorithm.Mode    = CipherMode.ECB;
            _algorithm.Padding = PaddingMode.None;

            BlockLength = _algorithm.BlockSize / 8;

            _transform = keyWrapDirection == KeyWrapDirection.Encrypt ? _algorithm.CreateEncryptingTransform() : _algorithm.CreateDecryptingTransform();
        }
Exemplo n.º 2
0
        private static byte[] F(string password, Salt salt, int derivationIterations)
        {
            HMAC hmacsha512 = New <HMACSHA512>().Initialize(new SymmetricKey(new UTF8Encoding(false).GetBytes(password)));

            hmacsha512.TransformBlock(salt.GetBytes(), 0, salt.Length, null, 0);
            byte[] iBytes = 1.GetBigEndianBytes();

            hmacsha512.TransformBlock(iBytes, 0, iBytes.Length, null, 0);
            hmacsha512.TransformFinalBlock(_empty, 0, 0);

            byte[] u  = hmacsha512.Hash();
            byte[] un = u;

            for (int c = 2; c <= derivationIterations; ++c)
            {
                hmacsha512.Initialize();
                hmacsha512.TransformBlock(u, 0, u.Length, null, 0);
                hmacsha512.TransformFinalBlock(_empty, 0, 0);
                u = hmacsha512.Hash();
                for (int i = 0; i < u.Length; i++)
                {
                    un[i] ^= u[i];
                }
            }

            return(un);
        }