예제 #1
0
        /// <summary>
        /// Устанавливает первичные настройки для блоков текста и ключа
        /// </summary>
        /// <param name="blockSize"></param>
        /// <param name="keySize"></param>
        /// <param name="key"></param>
        public void SetSettings(BlockSize blockSize, KeySize keySize, byte[] key)
        {
            var keyLengthInBytes = RijndaelSizesConverter.KeySizeToInt(keySize) / 8;

            if (key.Length != keyLengthInBytes)
            {
                throw new Exception("Неверная длина ключа");
            }

            _blockSize = blockSize;
            _keySize   = keySize;
            _key       = key;

            GenerateKeyExpansion();
        }
예제 #2
0
        /// <summary>
        /// Генерирует набор ключей для шифрования и дешифрования
        /// </summary>
        private void GenerateKeyExpansion()
        {
            var blockSize = _blockSize;
            var keySize   = _keySize;
            var key       = _key;

            var blockSizeBits = RijndaelSizesConverter.BlockSizeToInt(blockSize);
            var nb            = blockSizeBits / 32;
            var nr            = GetAmountRounds(blockSize, keySize);               // amount rounds
            var nk            = RijndaelSizesConverter.KeySizeToInt(keySize) / 32; // amount of columns

            switch (blockSizeBits > key.Length * 8 ? blockSizeBits : key.Length * 8)
            {
            case 128:
                nr = 10;
                break;

            case 192:
                nr = 12;
                break;

            case 256:
                nr = 14;
                break;

            default:
                throw new Exception("InvalidKeySize");
            }

            _encryptKeyExpansion = new int[nb * (nr + 1)];
            _decryptKeyExpansion = new int[nb * (nr + 1)];
            int iTemp;

            var index = 0;

            for (var i = 0; i < nk; ++i)
            {
                int i0 = key[index++];
                int i1 = key[index++];
                int i2 = key[index++];
                int i3 = key[index++];
                _encryptKeyExpansion[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0;
            }

            if (nk <= 6)
            {
                for (var i = nk; i < nb * (nr + 1); ++i)
                {
                    iTemp = _encryptKeyExpansion[i - 1];

                    if (i % nk == 0)
                    {
                        iTemp  = SubWord(Rot3(iTemp));
                        iTemp ^= RijndaelTables.Rcon[(i / nk) - 1];
                    }

                    _encryptKeyExpansion[i] = _encryptKeyExpansion[i - nk] ^ iTemp;
                }
            }
            else
            {
                for (var i = nk; i < nb * (nr + 1); ++i)
                {
                    iTemp = _encryptKeyExpansion[i - 1];

                    if (i % nk == 0)
                    {
                        iTemp  = SubWord(Rot3(iTemp));
                        iTemp ^= RijndaelTables.Rcon[(i / nk) - 1];
                    }
                    else if (i % nk == 4)
                    {
                        iTemp = SubWord(iTemp);
                    }

                    _encryptKeyExpansion[i] = _encryptKeyExpansion[i - nk] ^ iTemp;
                }
            }

            for (var i = 0; i < nb; ++i)
            {
                _decryptKeyExpansion[i]           = _encryptKeyExpansion[i];
                _decryptKeyExpansion[nb * nr + i] = _encryptKeyExpansion[nb * nr + i];
            }

            for (var i = nb; i < nb * nr; ++i)
            {
                var tmpKey = _encryptKeyExpansion[i];
                var mul02  = MulX(tmpKey);
                var mul04  = MulX(mul02);
                var mul08  = MulX(mul04);
                var mul09  = tmpKey ^ mul08;
                _decryptKeyExpansion[i] = mul02 ^ mul04 ^ mul08 ^ Rot3(mul02 ^ mul09) ^ Rot2(mul04 ^ mul09) ^ Rot1(mul09);
            }

            for (var i = 0; i < nr + 1; i++)
            {
                for (var k = 0; k < nb; k++)
                {
                    _decryptKeyExpansion[i * nb + k] = _encryptKeyExpansion[(nr - i) * nb + k];
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Ничего интересного. Читаем файл, шифруем/дешифруем его. Решаем пролему некратных блоков.
        /// </summary>
        /// <param name="inFile"></param>
        /// <param name="outFile"></param>
        /// <param name="handler"></param>
        /// <param name="isEncrypting"></param>
        void ProcessFileANSIX923(FileStream inFile, FileStream outFile, Func <byte[], byte[]> handler, bool isEncrypting)
        {
            var amountBytesInBlock = RijndaelSizesConverter.BlockSizeToInt(_blockSize) / 8;

            var fileSize = inFile.Length;

            var blocksAmount = fileSize / amountBytesInBlock;

            SetMaximum(blocksAmount);

            var oneTick = blocksAmount / 100 + 1;

            // при дешифровке блоков должно быть минимум 2 и размер должен быть кратен блоку
            var incorrectFile = (fileSize % amountBytesInBlock != 0) && !isEncrypting;

            if (incorrectFile)
            {
                throw new Exception("Неверный формат файла");
            }

            var readedBlocksAmount = 0;

            var inData          = new byte[amountBytesInBlock];
            var outData         = new byte[0];
            int readBytesAmount = 0;

            while (true)
            {
                readBytesAmount = inFile.Read(inData, 0, inData.Length);
                if (readBytesAmount != amountBytesInBlock)
                {
                    break;
                }

                readedBlocksAmount++;

                outData = handler(inData);

                var isLast = blocksAmount == readedBlocksAmount;
                if (isLast && !isEncrypting)
                {
                    // последний блок при расшифровке прочитан
                    var amount = outData[amountBytesInBlock - 1];
                    if (amount < 0 || amount > amountBytesInBlock)
                    {
                        throw new Exception("Неверный формат файла");
                    }
                    outFile.Write(outData, 0, amount);
                }
                else
                {
                    outFile.Write(outData, 0, outData.Length);
                }

                inData = new byte[amountBytesInBlock];

                SetValue(readedBlocksAmount);
            }

            var gCount = (byte)(inFile.Length % amountBytesInBlock); // сколько байт осталось в потоке

            if (isEncrypting)
            {
                // старшие биты пусты - в самый старший добавить (8 - gCount)

                if (gCount != amountBytesInBlock)
                {
                    inData[amountBytesInBlock - 1] = gCount;
                }

                //  зашифруем данные
                outData = handler(inData);
                outFile.Write(outData, 0, amountBytesInBlock);

                if (gCount == amountBytesInBlock)
                {
                    //  добавим gcount в конец файла зашифровав его
                    var gCountIn = new byte[amountBytesInBlock];
                    gCountIn[0] = gCount;
                    var gCountOut = handler(gCountIn);
                    outFile.Write(gCountOut, 0, amountBytesInBlock);
                }
            }
        }
예제 #4
0
 public RijndaelKey(BlockSize blockSize, int[] keyExpansion, int offset)
     : base(RijndaelSizesConverter.BlockSizeToInt(blockSize) / 32)
 {
     LoadFromKeyExpansion(keyExpansion, offset);
 }
예제 #5
0
 public RijndaelState(BlockSize blockSize, byte[] block)
     : base(RijndaelSizesConverter.BlockSizeToInt(blockSize) / 32)
 {
     LoadFromBlock(block);
 }