Esempio n. 1
0
        public static ArrayLease <byte> DecryptBytes(ArraySegment <byte> ciphertext, ArraySegment <byte> key, out int count)
        {
            // Blowfish processes things in blocks of 8, so
            // it doesn't make sense to have a non-multiple
            // of 8 length ciphertext (TODO: right?)
            if ((ciphertext.Count & 7) != 0) // ciphertext.Count % 8 != 0
            {
                // TODO: Have a Strings.resx file for this
                // Does project.json support that? / What benefits will that yield?
                throw new ArgumentException(
                          message: "The length of the ciphertext needs to be divisible by 8.",
                          paramName: nameof(ciphertext));
            }

            // Since there's guaranteed to be no leftover,
            // the count is just ciphertext.Count
            count = ciphertext.Count;

            var engine       = new BlowfishEngine();
            var keyParameter = new KeyParameter(key.Array, key.Offset, key.Count);

            engine.Init(forEncryption: false, parameters: keyParameter);

            var lease = ArrayPool <byte> .Shared.Lease(count);

            try
            {
                var encryptBuffer = ciphertext.Array;
                var decryptBuffer = lease.Array;

                for (int i = 0; i < count; i += 8)
                {
                    engine.ProcessBlock(encryptBuffer, ciphertext.Offset + i, decryptBuffer, i);
                }
            }
            catch
            {
                lease.Dispose();
                throw;
            }

            return(lease);
        }
        static byte[] decrypt(byte[] byteArray, BlowfishEngine bf)
        {
            int         blockSize = 8;
            List <byte> decrypted = new List <byte>();

            for (int i = 0; i < byteArray.Length; i = i + blockSize)
            {
                byte[] blockBytes = new byte[blockSize];
                byte[] outBytes   = new byte[blockSize];
                for (int j = 0; j < blockSize; j++)
                {
                    blockBytes[j] = byteArray[i + j];
                }
                bf.ProcessBlock(blockBytes, 0, outBytes, 0);
                decrypted.AddRange(outBytes);
            }
            unpad(decrypted);
            return(decrypted.ToArray());
        }
Esempio n. 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>
        /// <returns>The encrypted data.</returns>
        public byte[] Encrypt(byte[] data, string passphrase)
        {
            // Create the key parameters.
            byte[] key = Encoding.Default.GetBytes(passphrase);
            Key.Crypto.Parameters.KeyParameter keyParameter = new KeyParameter(key);

            // Initialise the cryptography engine.
            Key.Crypto.Engines.BlowfishEngine blowfish = new BlowfishEngine();
            blowfish.Init(true, keyParameter);

            int dataLength   = data.Length;
            int blockSize    = blowfish.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.
                blowfish.ProcessBlock(decryptedData, (i * blockSize), encryptedData, (i * blockSize));
            }

            // Return the encrypted data.
            return(encryptedData);
        }
Esempio n. 4
0
        private void decrypt(byte[] value, BlowfishEngine bf)
        {
            int blockSize = bf.GetBlockSize();

            byte[] vector = new byte[blockSize];
            for (int i = 0; i < blockSize; i++)
            {
                vector[i] = 0;
            }
            for (int i = 0; i < value.Length; i += blockSize)
            {
                byte[] tmp = new byte[blockSize];
                bf.ProcessBlock(vector, 0, tmp, 0);
                int chunk = Math.Min(blockSize, value.Length - i);
                for (int j = 0; j < chunk; j++)
                {
                    vector[j]      = value[i + j];
                    value[(i + j)] = (byte)(value[(i + j)] ^ tmp[j]);
                }
                ;
            }
            ;
        }
Esempio n. 5
0
        private static byte[] ProcessData(byte[] data, byte[] key, bool forEncryption)
        {
            byte[] input = data;

            bool paddingRequired = data.Length % BlockSize > 0;

            if (paddingRequired)
            {
                input = new byte[data.Length + BlockSize - data.Length % BlockSize];
                Buffer.BlockCopy(data, 0, input, 0, data.Length);
            }

            byte[] output = new byte[input.Length];

            BlowfishEngine engine = new BlowfishEngine();

            engine.Init(forEncryption, key);

            int offset = 0;

            while (offset < input.Length)
            {
                engine.ProcessBlock(input, offset, output, offset);

                offset += BlockSize;
            }

            if (paddingRequired)
            {
                byte[] unpaddedOutput = new byte[data.Length];
                Buffer.BlockCopy(output, 0, unpaddedOutput, 0, unpaddedOutput.Length);
                return(unpaddedOutput);
            }

            return(output);
        }
Esempio n. 6
0
        public static ArrayLease <byte> EncryptBytes(ArraySegment <byte> plaintext, ArraySegment <byte> key, out int count)
        {
            // Blowfish encrypts 8 bytes at a time
            int leftover = plaintext.Count & 7;

            count = (plaintext.Count + 7) & ~7; // branchless version of: n - (n % 8) + 8

            // if there's leftover we'll need another extra 8 bytes to hold the input
            // note that this should not be part of the outputted array,
            // so store it in a new variable
            int capacity = count + ((leftover + 7) & ~7);

            Debug.Assert(leftover == 0 ^ capacity != plaintext.Count);

            var engine       = new BlowfishEngine();
            var keyParameter = new KeyParameter(key.Array, key.Offset, key.Count);

            engine.Init(forEncryption: true, parameters: keyParameter);

            var lease = ArrayPool <byte> .Shared.Lease(capacity);

            try
            {
                int    i      = plaintext.Offset;
                int    j      = 0;
                byte[] input  = plaintext.Array;
                byte[] output = lease.Array;

                // Process each block of bytes
                while (i + 7 < plaintext.Count)
                {
                    engine.ProcessBlock(input, i, output, j);

                    i += 8;
                    j += 8;
                }

                Debug.Assert(
                    i + leftover == plaintext.Count &&
                    leftover >= 0 &&
                    leftover < 8);

                if (leftover != 0)
                {
                    // Handle the leftover input bytes

                    Debug.Assert(
                        count > plaintext.Count &&
                        (count % 8) == 0 &&
                        capacity == count + 8);

                    // Copy over the remaining input data to the end of the output array
                    int inputIndex = i, outputIndex = j + 8;
                    while (inputIndex < plaintext.Count)
                    {
                        output[outputIndex++] = input[inputIndex++];
                    }

                    // Since this is a rented array, clear any extraneous data at the end
                    // Use a regular while loop, since it's less than 8 bytes
                    Debug.Assert(
                        outputIndex <= capacity &&
                        capacity - outputIndex < 8);
                    while (outputIndex < capacity)
                    {
                        output[outputIndex++] = 0;
                    }

                    engine.ProcessBlock(output, j + 8, output, j);
                }
            }
            catch
            {
                lease.Dispose();
                throw;
            }

            return(lease);
        }