Example #1
0
        private void Initialize()
        {
            rijndael = new RijndaelEngine();
            aesInitializationVector = new byte[CRYPTO_BLOCK_SIZE];
            int rawLength = 2 * password.Length;

            byte[] rawPassword   = new byte[rawLength + 8];
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            for (int i = 0; i < password.Length; i++)
            {
                rawPassword[i * 2]     = passwordBytes[i];
                rawPassword[i * 2 + 1] = 0;
            }
            for (int i = 0; i < salt.Length; i++)
            {
                rawPassword[i + rawLength] = salt[i];
            }


            const int    noOfRounds = (1 << 18);
            IList <byte> bytes      = new List <byte>();

            byte[] digest;

            //TODO slow code below, find ways to optimize
            for (int i = 0; i < noOfRounds; i++)
            {
                bytes.AddRange(rawPassword);

                bytes.AddRange(new[]
                {
                    (byte)i, (byte)(i >> 8), (byte)(i >> CRYPTO_BLOCK_SIZE)
                });
                if (i % (noOfRounds / CRYPTO_BLOCK_SIZE) == 0)
                {
                    digest = ComputeHash(bytes.ToArray());
                    aesInitializationVector[i / (noOfRounds / CRYPTO_BLOCK_SIZE)] = digest[19];
                }
            }

            digest = ComputeHash(bytes.ToArray());
            //slow code ends

            byte[] aesKey = new byte[CRYPTO_BLOCK_SIZE];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    aesKey[i * 4 + j] = (byte)
                                        (((digest[i * 4] * 0x1000000) & 0xff000000 |
                                          (uint)((digest[i * 4 + 1] * 0x10000) & 0xff0000) |
                                          (uint)((digest[i * 4 + 2] * 0x100) & 0xff00) |
                                          (uint)(digest[i * 4 + 3] & 0xff)) >> (j * 8));
                }
            }

            rijndael.Init(false, new KeyParameter(aesKey));
        }
Example #2
0
        private void Initialize()
        {
            _rijndael = new RijndaelEngine();
            _aesInitializationVector = new byte[CRYPTO_BLOCK_SIZE];
            int rawLength = 2 * _password.Length;

            byte[] rawPassword   = new byte[rawLength + 8];
            byte[] passwordBytes = Encoding.UTF8.GetBytes(_password);
            for (int i = 0; i < _password.Length; i++)
            {
                rawPassword[i * 2]     = passwordBytes[i];
                rawPassword[i * 2 + 1] = 0;
            }
            for (int i = 0; i < _salt.Length; i++)
            {
                rawPassword[i + rawLength] = _salt[i];
            }

            const int noOfRounds = (1 << 18);
            const int iblock     = 3;

            byte[] digest;
            byte[] data = new byte[(rawPassword.Length + iblock) * noOfRounds];

            //TODO slow code below, find ways to optimize
            for (int i = 0; i < noOfRounds; i++)
            {
                rawPassword.CopyTo(data, i * (rawPassword.Length + iblock));

                data[i * (rawPassword.Length + iblock) + rawPassword.Length + 0] = (byte)i;
                data[i * (rawPassword.Length + iblock) + rawPassword.Length + 1] = (byte)(i >> 8);
                data[i * (rawPassword.Length + iblock) + rawPassword.Length + 2] = (byte)(i >> CRYPTO_BLOCK_SIZE);

                if (i % (noOfRounds / CRYPTO_BLOCK_SIZE) == 0)
                {
                    digest = SHA1.Create().ComputeHash(data, 0, (i + 1) * (rawPassword.Length + iblock));
                    _aesInitializationVector[i / (noOfRounds / CRYPTO_BLOCK_SIZE)] = digest[19];
                }
            }
            digest = SHA1.Create().ComputeHash(data);
            //slow code ends

            byte[] aesKey = new byte[CRYPTO_BLOCK_SIZE];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    aesKey[i * 4 + j] = (byte)
                                        (((digest[i * 4] * 0x1000000) & 0xff000000 |
                                          (uint)((digest[i * 4 + 1] * 0x10000) & 0xff0000) |
                                          (uint)((digest[i * 4 + 2] * 0x100) & 0xff00) |
                                          (uint)(digest[i * 4 + 3] & 0xff)) >> (j * 8));
                }
            }

            _rijndael.Init(false, new KeyParameter(aesKey));
        }
Example #3
0
        /// <summary>
        /// Encrypted the data.
        /// </summary>
        /// <param name="data">The data to encrypted.</param>
        /// <param name="passphrase">The passphrase key used to mask the data.</param>
        /// <param name="blocksize">The blocksize in bits, must be 128, 192, or 256.</param>
        /// <returns>The encrypted data; else null.</returns>
        /// <remarks>The passphrase must be between 0 and 32 bytes in length.</remarks>
        public byte[] Encrypt(byte[] data, string passphrase, int blocksize = 256)
        {
            // Create the key length.
            byte[] key = GeneratePasswordBytes(passphrase);

            if (!VerifyKeySize(key))
            {
                return(null);
            }

            // Create the key parameters.
            Key.Crypto.Parameters.KeyParameter keyParameter = new KeyParameter(key);

            // Initialise the cryptography engine.
            Key.Crypto.Engines.RijndaelEngine rijndael = new RijndaelEngine(blocksize);
            rijndael.Init(true, keyParameter);

            int dataLength   = data.Length;
            int blockSize    = rijndael.GetBlockSize();
            int modBlockSize = dataLength % blockSize;
            int blockCount   = dataLength / blockSize;

            // If there is a remained then add en extra block count.
            if ((modBlockSize) > 0)
            {
                // Add one extra block.
                blockCount++;
            }

            // Encrypted data store.
            byte[] encryptedData = new byte[blockCount * blockSize];
            byte[] decryptedData = new byte[blockCount * blockSize];

            // Copy the decrypted data.
            for (int j = 0; j < dataLength; j++)
            {
                // Assign the data.
                decryptedData[j] = data[j];
            }

            // For each block size in the the data.
            for (int i = 0; i < blockCount; i++)
            {
                // Encrypt the block.
                rijndael.ProcessBlock(decryptedData, (i * blockSize), encryptedData, (i * blockSize));
            }

            // Return the encrypted data.
            return(encryptedData);
        }