using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;namespace ElGamalProgram
{
    class ElGamal
    {
        private const int MAXINT64LEN = sizeof(Int64);//用来作为读取的单位长度
        private const string tempPrePadding = "_elgpad";//用来生成paded文件的文件名
        private const string tempPreTransforming = "_elgtrans";//用来生成transformed文件的文件名
        private const int BITSLEN = 60;//密钥的长度
        private RandomPrimeGenerator r = new RandomPrimeGenerator();//用来生成随机数,及进行其他运算        private Int64 p;    //大素数
        private Int64 a;    //生成元
        private Int64 sk;   //私钥
        private Int64 pk;   //公钥        public ElGamal(Int64 p, Int64 sk)
        {
            this.p = p;
            this.sk = sk;
            
        }        public void init4Encode(Int64 a)
        {
            this.a = a;
            this.pk = r.modPower(a, sk, p);
        }        //将输入的文件进行变换之后,再加密,输出到输出文件中
        public void Encode(string inputFile, string outputFile)
        {
            string path = Path.GetDirectoryName(inputFile);
            string name = Path.GetFileName(inputFile);
            string transformedFile = path + "\\"+tempPreTransforming + name;
            prepare4Encoding(inputFile, transformedFile, p);
            ElGamalEncode(transformedFile, outputFile);
            File.Delete(transformedFile);
        }
        //将输入的文件进行变换之后,再解密,输出到输出文件中
        public void Decode(string inputFile, string outputFile)
        {
            string path = Path.GetDirectoryName(inputFile);
            string name = Path.GetFileName(inputFile);
            string decodedFile = path +"\\"+ tempPrePadding+name;
            ElGamalDecode(inputFile, decodedFile);
            postDecoding(decodedFile, outputFile, p);
            File.Delete(decodedFile);
        }
        //对于已经经过变换之后的文件,直接进行加密
        private void ElGamalEncode(string inputFile, string outputFile)
        {
            FileStream finput = openFile(inputFile);
            if (finput == null)
                return;
            FileStream foutput = createFile(outputFile);
            if (foutput == null)
                return;
            
            Int64 m;
            while ((m = inputInt64(finput)) != -1)
            {
                Int64 k = r.nextInt64(0, p - 1);
                Int64 y1 = r.modPower(a, k, p);
                byte[] temp = BitConverter.GetBytes(y1);
                foutput.Write(temp, 0, MAXINT64LEN);
                Int64 pk1 = r.modPower(pk, k, p);
                Int64 y2 = r.multiplyMod(m, pk1, p);
                foutput.Write(BitConverter.GetBytes(y2), 0, MAXINT64LEN);
            }
            finput.Close();
            foutput.Close();
        }
        
        //将变换之后的文件进行直接解密
        private void ElGamalDecode(string inputFile, string outputFile)
        {
            FileStream finput = openFile(inputFile);
            if (finput == null)
                return;
            FileStream foutput = createFile(outputFile);
            if (foutput == null)
                return;
            Int64 y1;
            while ((y1 = inputInt64(finput)) != -1)
            {
                Int64 y2 = inputInt64(finput);
                Int64 t = r.modPower(y1, sk, p);
                t = r.reverse(t, p);
                Int64 m = r.multiplyMod(y2, t, p);
                foutput.Write(BitConverter.GetBytes(m), 0, MAXINT64LEN);
            }
            finput.Close();
            foutput.Close();
        }        //将二进制串进行加密,结果存放在output1和output2中 
        public void ElGamalEncodeBits(Int64 input, out Int64 output1, out Int64 output2)
        {
            Int64 k = r.nextInt64(0, p - 1);
            output1 = r.modPower(a, k, p);
            Int64 pk1 = r.modPower(pk, k, p);
            output2 = r.multiplyMod(input, pk1, p);
        }
        //将二进制串进行解密,结果存放在input中
        public void ElGamalDecodeBits(out Int64 input, Int64 output1, Int64 output2)
        {
            Int64 t = r.modPower(output1, sk, p);
            t = r.reverse(t, p);
            input = r.multiplyMod(output2, t, p);
        }
        //从文件流finput中读入一个Int64型数据
        private Int64 inputInt64(FileStream finput)
        {
            byte[] temp = new byte[MAXINT64LEN];
            int count = finput.Read(temp, 0, MAXINT64LEN);
            if (count == 0)
                return -1;
            Int64 result = BitConverter.ToInt64(temp, 0);
            return result;
        }
        //为加密做准备
        private void prepare4Encoding(string inputFile, string transformedFile, Int64 p0)
        {
            FileStream finput = openFile(inputFile);
            if (finput == null)
                return;
            string path = Path.GetDirectoryName(inputFile);
            string name = Path.GetFileName(inputFile);
            string paddedFile = path + "\\"+tempPrePadding + name;
            FileStream fPadded = createFile(paddedFile);
            if (fPadded == null)
                return;
            FileStream fTransformed = createFile(transformedFile);
            if (fTransformed == null)
                return;
            padding_Transform(finput, fPadded, fTransformed, p0);
            File.Delete(paddedFile);
        }
        //在解密完成之后,进行变换
        private void postDecoding(string decodedFile, string depaddedFile, Int64 p0)
        {
            FileStream fDecoded = openFile(decodedFile);
            if (fDecoded == null)
                return;
            string path = Path.GetDirectoryName(decodedFile);
            string name = Path.GetFileName(decodedFile);
            string detransformedFile = path + "\\"+tempPreTransforming + name;
            FileStream fDetransformed = createFile(detransformedFile);
            if (fDetransformed == null)
                return;
            FileStream fDepadded = createFile(depaddedFile);
            if (fDepadded == null)
                return;
            detransform_Depadding(fDecoded, fDetransformed, fDepadded, p0);
            File.Delete(detransformedFile);
        }
        

解决方案 »

  1.   

    剩余的。。
            //辅助函数
            private FileStream openFile(string fileName)
            {
                FileStream file = new FileStream(fileName, FileMode.Open);
                if (!file.CanRead)
                {
                    string complain = "不能打开文件" + file + "!";
                    errorComplain(complain);
                    file.Close();
                    return null;
                }
                return file;
            }
            //辅助函数
            private FileStream createFile(string fileName)
            {
                FileStream file = new FileStream(fileName, FileMode.Create);
                if (!file.CanWrite)
                {
                    string complain = "不能创建文件" + file + "!";
                    errorComplain(complain);
                    file.Close();
                    return null;
                }
                return file;
            }
            //辅助函数
            private void errorComplain(string complain)
            {
                MessageBox.Show(complain, "Error");
            }
            //进行padding的变换
            private void padding_Transform(FileStream finput, FileStream fPadded, FileStream fTransformed, Int64 p0)
            {
                finput.CopyTo(fPadded);
                encodePadding(fPadded);
                fPadded.Seek(0, SeekOrigin.Begin);
                encodeTransform(fPadded, fTransformed, p0);            finput.Close();
                fPadded.Close();
                fTransformed.Close();
            }
            //逆变换
            private void detransform_Depadding(FileStream fDecoded, FileStream fDetransformed, FileStream fDepadded, Int64 p0)
            {
                decodeDeTransform(fDecoded, fDetransformed, p0);
                fDetransformed.Seek(0, SeekOrigin.Begin);
                decodeDePadding(fDetransformed, fDepadded, p0);            fDecoded.Close();
                fDetransformed.Close();
                fDepadded.Close();
            }
            //padding
            private void encodePadding(FileStream foutput)
            {
                Int64 size = foutput.Length;
                Int64 residue;
                residue = size % MAXINT64LEN;
                residue = MAXINT64LEN - residue;
                for (Int64 i = 0; i < residue; i++)
                    foutput.WriteByte(0);
                byte[] temp = BitConverter.GetBytes(size);
                foutput.Write(temp, 0, MAXINT64LEN);
            }        private void encodeTransform(FileStream fPadded, FileStream fTransformed, Int64 p0)
            {
                UInt64 p = (UInt64)p0;
                byte[] tempForInputM = new byte[MAXINT64LEN];
                byte[] tempForOutputM;
                while (fPadded.Read(tempForInputM, 0, MAXINT64LEN) != 0)
                {
                    UInt64 m = BitConverter.ToUInt64(tempForInputM, 0);
                    tempForOutputM = BitConverter.GetBytes(m / p + 1);
                    fTransformed.Write(tempForOutputM, 0, MAXINT64LEN);
                    tempForOutputM = BitConverter.GetBytes(m % p + 1);
                    fTransformed.Write(tempForOutputM, 0, MAXINT64LEN);
                }
            }
            private void decodeDeTransform(FileStream fDecoded, FileStream fDetransformed, Int64 p0)
            {
                UInt64 p = (UInt64)p0;
                byte[] tempForOutputM = new byte[MAXINT64LEN];
                while (fDecoded.Read(tempForOutputM, 0, MAXINT64LEN) != 0)
                {
                    UInt64 m1 = BitConverter.ToUInt64(tempForOutputM, 0);
                    fDecoded.Read(tempForOutputM, 0, MAXINT64LEN);
                    UInt64 m2 = BitConverter.ToUInt64(tempForOutputM, 0);
                    m1 -= 1;
                    m2 -= 1;
                    UInt64 m = m1 * p + m2;
                    fDetransformed.Write(BitConverter.GetBytes(m), 0, MAXINT64LEN);
                }
            }
            private void decodeDePadding(FileStream fDetransformed, FileStream fDepadded, Int64 p0)
            {
                UInt64 p = (UInt64)p0;
                byte[] tempForOutputM1 = new byte[MAXINT64LEN];
                byte[] tempForOutputM2 = new byte[MAXINT64LEN];
                Int64 size = fDetransformed.Length;
                while (fDetransformed.Read(tempForOutputM1, 0, MAXINT64LEN) != 0)
                {
                    //如果是倒数第二个字符
                    if (fDetransformed.Position == size - 1 * MAXINT64LEN)
                    {
                        UInt64 padding = BitConverter.ToUInt64(tempForOutputM1, 0);
                        fDetransformed.Read(tempForOutputM2, 0, MAXINT64LEN);
                        UInt64 fileLen = BitConverter.ToUInt64(tempForOutputM2, 0);
                        UInt64 residue = fileLen % MAXINT64LEN;
                        for (UInt64 i = 0; i < residue; i++)
                            fDepadded.WriteByte(tempForOutputM1[i]);
                        return;
                    }
                    else
                    {
                        fDepadded.Write(tempForOutputM1, 0, MAXINT64LEN);
                    }
                }        }
            /*static void Main(string[] args)
            {
                RandomPrimeGenerator r = new RandomPrimeGenerator();
                Int64 p = r.RandomSafePrime(60);
                Int64 a = r.generator(p);
                Int64 k = r.nextInt64(0, p-1);
                Int64 sk = r.nextInt64(1, p - 1);
                ElGamal e = new ElGamal(p, sk);
                Int64 output1 = 0, output2 = 0;
                e.ElGamalEncodeBits(1243424,out output1,out output2);
                Console.WriteLine(output1);
                Console.WriteLine(output2);
            }*/
        }
    }
      

  2.   

    你可以试一下这个工具
    http://download.csdn.net/detail/shjh369/3204008