Пример #1
0
        /// <summary>Encrypt a byte array in blocks with AES algorithm in CBC mode.</summary>
        /// <remarks>Encrypt a byte array in blocks with AES algorithm in CBC mode.</remarks>
        /// <param name="plainInput">Plain byte array to encrypt</param>
        /// <param name="key">256 Bit key to encrypt plainInput</param>
        /// <returns>Return encrypted byte array</returns>
        public virtual byte[] encrypt(byte[] plainInput, byte[] key)
        {
            int inputLength = plainInput.Length;
            int percentProgress;
            int prevPercent = -1;

            byte[] inputLengthByte = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(inputLength).array();
            int    restInput       = plainInput.Length % nBytes;

            byte[] exKey        = initKeyExpand(key);
            byte[] cipher       = new byte[nBytes];
            byte[] cryptOutput  = new byte[(inputLength - restInput) + nBytes * 2];
            int    outputLength = cryptOutput.Length;

            byte[]       initVector = new byte[nBytes];
            byte[]       nextBlock  = new byte[nBytes];
            SecureRandom scRandom   = new SecureRandom();

            // Copy plaintext Array into crypt Array
            System.Array.Copy(plainInput, 0, cryptOutput, 0, inputLength);
            // Fill Initialization Vector with Random Bytes
            scRandom.nextBytes(initVector);
            // Copy first Input Block to nextBlock
            System.Array.Copy(cryptOutput, 0, nextBlock, 0, nBytes);
            // XOR Random initVektor with first Input Block
            nextBlock = CryptobyHelper.xorByteArrays(nextBlock, initVector);
            // Copy xored prevBlock into first Input Block
            System.Array.Copy(nextBlock, 0, cryptOutput, 0, nBytes);
            // Encrypt last BlockArray
            initVector = encryptCipher(initVector, exKey);
            // Add the initVector Array in to last BlockArray and encrypt it
            System.Array.Copy(initVector, 0, cryptOutput, outputLength - nBytes, nBytes);
            // Add in the first Byte after CryptText the origin length of plaintext Array
            System.Array.Copy(inputLengthByte, 0, cryptOutput, outputLength - nBytes * 2, 4);
            // Encrypt every Block in CBC Mode
            for (int i = 0; i < outputLength - nBytes; i += nBytes)
            {
                // Convert i to percent for ProgressBar
//				percentProgress = (int)(((float)i / (float)(outputLength - nBytes)) * 100);
//				// Print ProgressBar
//				if (percentProgress > prevPercent)
//				{
//					CryptobyHelper.printProgressBar(percentProgress);
//				}
//				prevPercent = percentProgress;
                // Copy current block in to Cipher Array
                System.Array.Copy(nextBlock, 0, cipher, 0, nBytes);
                // Encrypt Cipher
                cipher = this.encryptCipher(cipher, exKey);
                // CBC Mode: XOR next PlainBlock with encrypted Cipher
                if (i + nBytes < outputLength)
                {
                    System.Array.Copy(cryptOutput, i + nBytes, nextBlock, 0, nBytes);
                    nextBlock = CryptobyHelper.xorByteArrays(nextBlock, cipher);
                }
                // Copy Cipher back in decryptOutput Array
                System.Array.Copy(cipher, 0, cryptOutput, i, nBytes);
            }
//			CryptobyHelper.printProgressBar(100);
            return(cryptOutput);
        }
Пример #2
0
        /// <summary>Encrypt plainInput with publicKey in blocks.</summary>
        /// <remarks>
        /// Encrypt plainInput with publicKey in blocks. The first encrypted block will
        /// be xored with a Initial Vektor and every next encrypted block will be xored
        /// with the previous block and written to output array. Encrypted Initial
        /// Vector stored in last two bytes of output byte array.
        /// </remarks>
        /// <param name="plainInput">Byte Array to encrypt in RSA Mode</param>
        /// <param name="publicKey">RSA Public Key as Byte Array</param>
        /// <returns>RSA Encrypted plainInput as Byte Array</returns>
        public virtual byte[] encrypt(byte[] plainInput, byte[] publicKey)
        {
            BigInteger n             = new BigInteger(publicKey);
            int        keySize       = publicKey.Length;
            int        dataBlockSize = keySize + 2 * (keySize / 128);

            int plainBlockSize = keySize - 2;
            int wholeLen       = plainInput.Length;
            int cryptBlocksLen = (wholeLen / plainBlockSize) * dataBlockSize;

            int dataBlocksLen = cryptBlocksLen + 3 * dataBlockSize;

            int plainBlocksLen = (wholeLen / plainBlockSize) * plainBlockSize;

            byte[] cryptOutput = new byte[dataBlocksLen];
            if (wholeLen > keySize)
            {
                int    percentProgress;
                int    prevPercent           = -1;
                int    plainPlusOneBlockSize = plainBlockSize + 1;
                int    rest = wholeLen - plainBlocksLen;
                int    halfOfVektor;
                byte[] dataBlock = new byte[dataBlockSize];
                byte[] cryptBlock;
                byte[] plainBlock        = new byte[plainBlockSize];
                byte[] plusOnePlainBlock = new byte[plainPlusOneBlockSize];
                byte[] initVektorBlock;
                byte[] firstVektorBlock;
                byte[] secVektorBlock;
                byte[] cryptBlockSize;
                byte[] one = BigInteger.ONE.toByteArray();
                do
                {
                    SecureRandom rnd = new SecureRandom();
                    halfOfVektor = dataBlockSize / 2;
                    do
                    {
                        firstVektorBlock = new BigInteger(halfOfVektor * 8 - 1, rnd).toByteArray();
                        secVektorBlock   = new BigInteger(halfOfVektor * 8 - 1, rnd).toByteArray();
                    }while (firstVektorBlock.Length != halfOfVektor || secVektorBlock.Length != halfOfVektor);
                    initVektorBlock = new byte[dataBlockSize];
                    System.Array.Copy(firstVektorBlock, 0, initVektorBlock, 0, halfOfVektor);
                    System.Array.Copy(secVektorBlock, 0, initVektorBlock, halfOfVektor, halfOfVektor);
                    firstVektorBlock = encryptBlock(firstVektorBlock, n);
                    secVektorBlock   = encryptBlock(secVektorBlock, n);
                }while (firstVektorBlock.Length != keySize || secVektorBlock.Length != keySize);
                byte[] prevBlock = new byte[dataBlockSize];
                System.Array.Copy(initVektorBlock, 0, prevBlock, 0, dataBlockSize);
                byte[] nextBlock = new byte[dataBlockSize];
                int    j         = 0;
                for (int i = 0; i < plainBlocksLen; i += plainBlockSize)
                {
                    // Convert i to percent for ProgressBar
                    percentProgress = (int)(((float)i / (float)plainBlocksLen) * 100);
                    // Print ProgressBar
//					if (percentProgress > prevPercent)
//					{
//						CryptobyHelper.printProgressBar(percentProgress);
//					}
                    prevPercent = percentProgress;
                    // Copy Part of PlainInput in to Block
                    System.Array.Copy(plainInput, i, plainBlock, 0, plainBlockSize);
                    // Add a One Byte into first Byte of Plain Array
                    System.Array.Copy(one, 0, plusOnePlainBlock, 0, one.Length);
                    System.Array.Copy(plainBlock, 0, plusOnePlainBlock, 1, plainBlockSize);
                    // Encrypt Block
                    cryptBlock = encryptBlock(plusOnePlainBlock, n);
                    // Copy Crypt Block in to extended DataBlock
                    System.Array.Copy(cryptBlock, 0, dataBlock, 0, cryptBlock.Length);
                    // Copy in last Byte of dataBlock the Size of cryptBlock
                    cryptBlockSize = BigInteger.valueOf(cryptBlock.Length - keySize).toByteArray();
                    System.Array.Copy(cryptBlockSize, 0, dataBlock, dataBlock.Length - 1, cryptBlockSize
                                      .Length);
                    System.Array.Copy(dataBlock, 0, nextBlock, 0, dataBlockSize);
                    // XOR dataBlock with prevBlock
                    dataBlock = CryptobyHelper.xorByteArrays(dataBlock, prevBlock);
                    System.Array.Copy(nextBlock, 0, prevBlock, 0, dataBlockSize);
                    // Copy xored dataBlock to Output Array
                    System.Array.Copy(dataBlock, 0, cryptOutput, j, dataBlockSize);
                    j += dataBlockSize;
                }
                if (rest != 0)
                {
                    // crypt rest of PlainInput
                    plainBlock        = new byte[rest];
                    plusOnePlainBlock = new byte[rest + 1];
                    dataBlock         = new byte[dataBlockSize];
                    System.Array.Copy(plainInput, plainBlocksLen, plainBlock, 0, plainBlock.Length);
                    // Add a One Byte in to first Byte of Plain Array
                    System.Array.Copy(one, 0, plusOnePlainBlock, 0, one.Length);
                    System.Array.Copy(plainBlock, 0, plusOnePlainBlock, 1, plainBlock.Length);
                    // Encrypt rest of PlainInput
                    cryptBlock = encryptBlock(plusOnePlainBlock, n);
                    System.Array.Copy(cryptBlock, 0, dataBlock, 0, cryptBlock.Length);
                    // Copy in last Byte of dataBlock the Size of cryptBlock
                    cryptBlockSize = BigInteger.valueOf(cryptBlock.Length - keySize).toByteArray();
                    System.Array.Copy(cryptBlockSize, 0, dataBlock, dataBlock.Length - 1, 1);
                    // XOR dataBlock with prevBlock
                    dataBlock = CryptobyHelper.xorByteArrays(dataBlock, prevBlock);
                    System.Array.Copy(dataBlock, 0, cryptOutput, dataBlocksLen - 3 * dataBlockSize, dataBlockSize
                                      );
                }
                else
                {
                    dataBlock = new byte[dataBlockSize];
                    System.Array.Copy(dataBlock, 0, cryptOutput, dataBlocksLen - 3 * dataBlockSize, dataBlockSize
                                      );
                }
                // Put crypted initVektor into last 2 Bytes of cryptOutput Array
                System.Array.Copy(firstVektorBlock, 0, cryptOutput, dataBlocksLen - 2 * dataBlockSize
                                  , firstVektorBlock.Length);
                System.Array.Copy(secVektorBlock, 0, cryptOutput, dataBlocksLen - 1 * dataBlockSize
                                  , secVektorBlock.Length);
            }
            else
            {
                cryptOutput = encryptBlock(plainInput, n);
            }
            //CryptobyHelper.printProgressBar(100);
            return(cryptOutput);
        }
Пример #3
0
        /// <summary>Decrypt a byte array in blocks with AES algorithm in CBC mode.</summary>
        /// <remarks>Decrypt a byte array in blocks with AES algorithm in CBC mode.</remarks>
        /// <param name="cryptInput">Encrypted byte array to decrypt</param>
        /// <param name="key">256 Bit key to decrypt cryptInput</param>
        /// <returns>Return decrypted byte array</returns>
        public virtual byte[] decrypt(byte[] cryptInput, byte[] key)
        {
            int percentProgress;
            int prevPercent = -1;

            byte[] exKey        = initKeyExpand(key);
            int    outputLength = cryptInput.Length;

            byte[] decryptOutput = new byte[outputLength];
            System.Array.Copy(cryptInput, 0, decryptOutput, 0, outputLength);
            byte[] cipher          = new byte[nBytes];
            byte[] inputLengthByte = new byte[nBytes];
            byte[] plainOutput;
            byte[] initVector = new byte[nBytes];
            byte[] prevBlock  = new byte[nBytes];
            // Add the initVector Array in to last BlockArray and encrypt it
            System.Array.Copy(decryptOutput, outputLength - nBytes, initVector, 0, nBytes);
            // Decrypt last BlockArray
            initVector = this.decryptCipher(initVector, exKey);
            // Copy initVector to prevBlock Array
            System.Array.Copy(initVector, 0, prevBlock, 0, nBytes);
            for (int i = 0; i < outputLength - nBytes; i += nBytes)
            {
//				// Convert i to percent for ProgressBar
//				percentProgress = (int)(((float)i / (float)(outputLength - nBytes)) * 100);
//				// Print ProgressBar
//				if (percentProgress > prevPercent)
//				{
//					CryptobyHelper.printProgressBar(percentProgress);
//				}
//				prevPercent = percentProgress;
                // Copy current block in to Cipher Array
                System.Array.Copy(decryptOutput, i, cipher, 0, nBytes);
                // Decrypt Cipher
                cipher = this.decryptCipher(cipher, exKey);
                // CBC Mode: XOR next PlainBlock with encrypted Cipher
                if (i + nBytes < outputLength)
                {
                    cipher = CryptobyHelper.xorByteArrays(prevBlock, cipher);
                    System.Array.Copy(decryptOutput, i, prevBlock, 0, nBytes);
                }
                // Copy Cipher back in current decryptOutput Array
                System.Array.Copy(cipher, 0, decryptOutput, i, nBytes);
            }
            // Read last Index of encryptet Output
            // and use the Integer Content for lenght of plainOutput
            System.Array.Copy(decryptOutput, outputLength - nBytes * 2, inputLengthByte, 0, 4);
            int lengthOriginArray = ByteBuffer.wrap(inputLengthByte).order(ByteOrder.BIG_ENDIAN
                                                                           ).getInt();

            try
            {
                plainOutput = new byte[lengthOriginArray];
                System.Array.Copy(decryptOutput, 0, plainOutput, 0, lengthOriginArray);
            }
            catch (Exception)
            {
                plainOutput = cryptInput;
            }
//			CryptobyHelper.printProgressBar(100);
            return(plainOutput);
        }
Пример #4
0
        /// <summary>Decrypt cryptInput with privateKey in blocks.</summary>
        /// <remarks>
        /// Decrypt cryptInput with privateKey in blocks. Initial Vector in last two
        /// bytes will be decrypt and used to xor the first decrypted block. Every next
        /// block will be xored with the previous block. After every XOR the block
        /// will be decrypted and written to output byte array.
        /// </remarks>
        /// <param name="cryptInput">RSA Encrypted Input as Byte Array</param>
        /// <param name="privateKey">RSA Private Key as Byte Array</param>
        /// <returns>RSA decrypted cryptInput as Byte Array</returns>
        public virtual byte[] decrypt(byte[] cryptInput, byte[] privateKey)
        {
            byte[]     dByteArray     = getDfromKey(privateKey);
            byte[]     nByteArray     = getNfromKey(privateKey);
            BigInteger d              = new BigInteger(dByteArray);
            BigInteger n              = new BigInteger(nByteArray);
            int        keySize        = nByteArray.Length;
            int        dataBlockSize  = keySize + 2 * (keySize / 128);
            int        plainBlockSize = keySize - 2;
            int        wholeLen       = cryptInput.Length;
            int        dataBlocksLen  = wholeLen - 3 * dataBlockSize;
            int        plainBlocksLen;
            int        halfOfVektor = dataBlockSize / 2;
            int        percentProgress;

            byte[] plainOutput;
            byte[] allPlainBlocks;
            byte[] cryptBlock;
            byte[] plainBlock = new byte[plainBlockSize];
            byte[] plusOnePlainBlock;
            byte[] dataBlock        = new byte[dataBlockSize];
            byte[] prevBlock        = new byte[dataBlockSize];
            byte[] initVektorBlock  = new byte[dataBlockSize];
            byte[] firstVektorBlock = new byte[keySize];
            byte[] secVektorBlock   = new byte[keySize];
            byte[] cryptBlockSize;
            if (wholeLen > keySize)
            {
                plainBlocksLen = (dataBlocksLen / dataBlockSize) * plainBlockSize;
                allPlainBlocks = new byte[plainBlocksLen];
                // Get initVektor from last 2 Bytes of CryptInput
                System.Array.Copy(cryptInput, wholeLen - 2 * dataBlockSize, firstVektorBlock, 0,
                                  keySize);
                System.Array.Copy(cryptInput, wholeLen - 1 * dataBlockSize, secVektorBlock, 0, keySize
                                  );
                // Decrypt Vektors and merge together
                firstVektorBlock = decryptBlock(firstVektorBlock, n, d);
                secVektorBlock   = decryptBlock(secVektorBlock, n, d);
                System.Array.Copy(firstVektorBlock, 0, initVektorBlock, 0, halfOfVektor);
                System.Array.Copy(secVektorBlock, 0, initVektorBlock, halfOfVektor, halfOfVektor);
                System.Array.Copy(initVektorBlock, 0, prevBlock, 0, dataBlockSize);
                int j = 0;
                for (int i = 0; i < dataBlocksLen; i += dataBlockSize)
                {
                    // Convert i to percent for ProgressBar
                    percentProgress = (int)(((float)i / (float)dataBlocksLen) * 100);
                    // Print ProgressBar
                    //CryptobyHelper.printProgressBar(percentProgress);
                    System.Array.Copy(cryptInput, i, dataBlock, 0, dataBlockSize);
                    // XOR with prevBlock
                    dataBlock = CryptobyHelper.xorByteArrays(prevBlock, dataBlock);
                    System.Array.Copy(dataBlock, 0, prevBlock, 0, dataBlockSize);
                    // Get Size of cryptBlock
                    cryptBlockSize = new byte[1];
                    System.Array.Copy(dataBlock, dataBlock.Length - 1, cryptBlockSize, 0, 1);
                    cryptBlock = new byte[keySize + new BigInteger(cryptBlockSize).intValue()];
                    System.Array.Copy(dataBlock, 0, cryptBlock, 0, cryptBlock.Length);
                    // Decrypt cryptBlock
                    plusOnePlainBlock = decryptBlock(cryptBlock, n, d);
                    // Remove one from first Byte of Array
                    System.Array.Copy(plusOnePlainBlock, 1, plainBlock, 0, plainBlockSize);
                    System.Array.Copy(plainBlock, 0, allPlainBlocks, j, plainBlockSize);
                    j += plainBlockSize;
                }
                dataBlock = new byte[dataBlockSize];
                System.Array.Copy(cryptInput, dataBlocksLen, dataBlock, 0, dataBlockSize);
                if (new BigInteger(dataBlock).compareTo(BigInteger.ZERO) != 0)
                {
                    dataBlock      = CryptobyHelper.xorByteArrays(prevBlock, dataBlock);
                    cryptBlockSize = new byte[1];
                    System.Array.Copy(dataBlock, dataBlock.Length - 1, cryptBlockSize, 0, 1);
                    cryptBlock = new byte[keySize + new BigInteger(cryptBlockSize).intValue()];
                    System.Array.Copy(dataBlock, 0, cryptBlock, 0, cryptBlock.Length);
                    plusOnePlainBlock = decryptBlock(cryptBlock, n, d);
                    plainBlock        = new byte[plusOnePlainBlock.Length - 1];
                    // Remove one from first Byte of Array
                    System.Array.Copy(plusOnePlainBlock, 1, plainBlock, 0, plainBlock.Length);
                    plainOutput = new byte[plainBlocksLen + plainBlock.Length];
                    System.Array.Copy(allPlainBlocks, 0, plainOutput, 0, plainBlocksLen);
                    System.Array.Copy(plainBlock, 0, plainOutput, plainBlocksLen, plainBlock.Length);
                }
                else
                {
                    plainOutput = new byte[plainBlocksLen];
                    System.Array.Copy(allPlainBlocks, 0, plainOutput, 0, plainBlocksLen);
                }
            }
            else
            {
                plainOutput = decryptBlock(cryptInput, n, d);
            }
            // Print ProgressBar
            //CryptobyHelper.printProgressBar(100);
            return(plainOutput);
        }