예제 #1
0
        private byte[] ValidatePassword(byte[] paddedPassword, byte[] password, byte [] uValue)
        {
            byte[] key   = new byte[Constants.KeySize];
            byte[] iv    = new byte[Constants.VectorSize];
            byte[] E16   = new byte[16];
            byte[] array = null;
            byte[] E     = null;
            byte[] K1    = null;
            int    idx   = 0;

            //Take the SHA - 256 hash of the original input to the algorithm
            //and name the resulting 32 bytes, K.
            byte[] K = sha256.ComputeHash(paddedPassword, 0, paddedPassword.Length);

            //The conditional-OR operator (||) performs a logical - OR
            //of its bool operands. If the first operand evaluates to true,
            //the second operand isn't evaluated. If the first operand evaluates
            //to false, the second operator determines whether the OR expression
            //as a whole evaluates to true or false.
            while (idx < 64 || E[E.Length - 1] + 32 > idx)
            {
                Array.Copy(K, key, key.Length);
                Array.Copy(K, 16, iv, 0, iv.Length);

                //Make a new string, K1, consisting of 64 repetitions of the sequence:
                //input password, K, the 48 - byte user key. The 48 byte user key is
                //only used when checking the owner password or creating the owner key.If
                //checking the user password or creating the user key, K1 is the
                //concatenation of the input password and K.
                K1    = new byte[(password.Length + K.Length + uValue.Length) * 64];
                array = arrayMath.ConcatByteArrays(password, K);
                array = arrayMath.ConcatByteArrays(array, uValue);

                for (int j = 0, pos = 0; j < 64; j++, pos += array.Length)
                {
                    Array.Copy(array, 0, K1, pos, array.Length);
                }

                //Encrypt K1 with the AES-128(CBC, no padding) algorithm,
                //using the first 16 bytes of K as the key and the second 16 bytes of
                //K as the initialization vector. The result of this encryption is E.
                E = aes.CreateEncryptor(key, iv).TransformFinalBlock(K1, 0, K1.Length);
                //Now we have to take the first 16 bytes of an unsigned big endian integer...
                //and compute the remainder modulo 3. Taking the first 16 bytes of E
                //as an unsigned big-endian integer, compute the remainder, modulo 3.
                Array.Copy(E, E16, E16.Length);
                BigInteger bigInteger = new BigInteger(E16.Reverse().Concat(new byte[] { 0x00 }).ToArray());
                byte[]     result     = BigInteger.Remainder(bigInteger, 3).ToByteArray();

                switch (result[0])
                {
                case 0x00:
                    K = sha256.ComputeHash(E, 0, E.Length);
                    break;

                case 0x01:
                    K = sha384.ComputeHash(E, 0, E.Length);
                    break;

                case 0x02:
                    K = sha512.ComputeHash(E, 0, E.Length);
                    break;

                default:
                    throw new Exception("Unexpected result while computing the remainder, modulo 3.");
                }
                idx++;
            }
            return(K);
        }