示例#1
0
        public byte[] Encrypt(byte[] text, IKey key = null)
        {
            Validate(text, key);

            ElgamalKey elgamalKey = key as ElgamalKey;

            if (elgamalKey.IsPrivate)
            {
                throw new ArgumentException("Для шифрования нужен публичный ключ");
            }

            List <byte> result = new List <byte>(text.Length);

            try
            {
                int readSize  = elgamalKey.MaxOpenTextSize;
                int writeSize = elgamalKey.MaxCipherTextSize;

                BigInteger k = Helper.GenerateBigInteger(2, elgamalKey.Parameters.P - 3);

                BigInteger r = BigInteger.ModPow(elgamalKey.Parameters.G, k, elgamalKey.Parameters.P);

                byte[] packedBlock = new byte[writeSize];

                byte[] rBlock = r.ToByteArray(false);
                Buffer.BlockCopy(rBlock, 0, packedBlock, 0, rBlock.Length);
                result.AddRange(packedBlock);

                for (int currentByte = 0; currentByte < text.Length; currentByte += readSize)
                {
                    int    byteCopyCount = Math.Min(readSize, text.Length - currentByte);
                    byte[] currentBlock  = new byte[byteCopyCount + 1];  // Добавлен 0х00 чтобы число было положительным

                    Buffer.BlockCopy(text, currentByte, currentBlock, 0, byteCopyCount);
                    BigInteger openInt   = new BigInteger(currentBlock);
                    BigInteger cipherInt = BigInteger.ModPow(elgamalKey.Key, k, elgamalKey.Parameters.P);
                    BigInteger.DivRem(openInt * cipherInt, elgamalKey.Parameters.P, out cipherInt);

                    byte[] cipherBlock = cipherInt.ToByteArray(false);
                    packedBlock = new byte[writeSize];
                    Buffer.BlockCopy(cipherBlock, 0, packedBlock, 0, cipherBlock.Length);
                    result.AddRange(packedBlock);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Ошибка! Проверьте входные параметры.", ex);
            }

            return(result.ToArray());
        }
示例#2
0
        public void Decrypt(string inputPath, string outputPath, IKey key, Action <double> ProgressChanged = null)
        {
            if (key is ElgamalKey == false)
            {
                throw new ArgumentException("Key is not ElgamalKey");
            }

            ElgamalKey elgamalKey = key as ElgamalKey;

            if (!elgamalKey.IsPrivate)
            {
                throw new ArgumentException("Для расшифровывания нужен закрытый ключ");
            }

            try
            {
                using FileStream instream  = File.OpenRead(inputPath);
                using FileStream outstream = File.Open(outputPath, FileMode.Create);

                long fileSize = instream.Length;

                int readSize = elgamalKey.MaxCipherTextSize * 1024 + elgamalKey.MaxCipherTextSize;

                byte[] inputChunk = new byte[readSize];
                int    size       = 0;

                while ((size = instream.Read(inputChunk, 0, readSize)) != 0)
                {
                    byte[] currentBlock;
                    if (size == readSize)
                    {
                        currentBlock = inputChunk;
                    }
                    else
                    {
                        currentBlock = new byte[size];
                        Buffer.BlockCopy(inputChunk, 0, currentBlock, 0, size);
                    }
                    byte[] outputChunk = Decrypt(currentBlock, elgamalKey);
                    outstream.Write(outputChunk, 0, outputChunk.Length);

                    int percent = ( int )((instream.Position * 100f) / fileSize);
                    ProgressChanged?.Invoke(percent);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Ошибка! Проверьте входные параметры.", ex);
            }
        }
示例#3
0
        public byte[] Decrypt(byte[] ciphertext, IKey key = null)
        {
            Validate(ciphertext, key);

            ElgamalKey elgamalKey = key as ElgamalKey;

            if (!elgamalKey.IsPrivate)
            {
                throw new ArgumentException("Для расшифровывания нужен закрытый ключ");
            }
            List <byte> result = new List <byte>(ciphertext.Length);

            try
            {
                int readSize  = elgamalKey.MaxCipherTextSize;
                int writeSize = elgamalKey.MaxOpenTextSize;

                byte[] rBlock = new byte[readSize + 1];
                Buffer.BlockCopy(ciphertext, 0, rBlock, 0, readSize);
                BigInteger r            = new BigInteger(rBlock);
                BigInteger decryptConst = BigInteger.ModPow(r, elgamalKey.Parameters.P - 1 - elgamalKey.Key, elgamalKey.Parameters.P);

                for (int currentByte = readSize; currentByte < ciphertext.Length; currentByte += readSize)
                {
                    int    byteCopyCount = Math.Min(readSize, ciphertext.Length - currentByte);
                    byte[] currentBlock  = new byte[byteCopyCount + 1];  // Добавлен 0х00 чтобы число было положительным

                    Buffer.BlockCopy(ciphertext, currentByte, currentBlock, 0, byteCopyCount);
                    BigInteger cipherInt = new BigInteger(currentBlock);
                    BigInteger openInt;
                    BigInteger.DivRem(cipherInt * decryptConst, elgamalKey.Parameters.P, out openInt);

                    byte[] openBlock   = openInt.ToByteArray(false);
                    byte[] packedBlock = new byte[writeSize];

                    Buffer.BlockCopy(openBlock, 0, packedBlock, 0, openBlock.Length);
                    result.AddRange(packedBlock);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Ошибка! Проверьте входные параметры.", ex);
            }

            return(result.ToArray());
        }