.net中不是有加密且可以解密的类吗?用它就得了!
System.security.cryptography命令空间下!

解决方案 »

  1.   

    这是我以前写的程序,和你的代码的功能差不多,测试通过。
    这个例子演示了如何使用RijndaelManaged类对文件进行对称加密
    using System;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;
    namespace ConsoleApplication2
    {
    class Class1
    {
    public static Byte[] ConvertStringToByteArray(String s)
    {
    return (new UnicodeEncoding()).GetBytes(s);
    }
    [STAThread]
    static void Main(string[] args)
    {
    Console.WriteLine("请输入需要加密的文件:");
    string infilename=(Console.ReadLine()).Trim();
    Console.WriteLine("请输入加密后文件保存的位置和文件名:");
    string outfilename=(Console.ReadLine()).Trim();
    Console.WriteLine("请输入密码:");
    //将输入的密码转化为字符数组
    byte[] originkey=(new UnicodeEncoding()).GetBytes(Console.ReadLine());
    try
    {
    //打开需要加密的文件
    FileStream infile=new FileStream(infilename,FileMode.Open,FileAccess.Read);
    //打开或创建密文件
    FileStream outfile=new FileStream(outfilename,FileMode.OpenOrCreate,FileAccess.Write);
    outfile.SetLength(0);
    //设置对称算法的初始化向量和取得密码和的哈希代码
    byte[] originiv=(new UnicodeEncoding()).GetBytes("abc");
    byte[] key=(new MD5CryptoServiceProvider()).ComputeHash(originkey);
    byte[] iv=(new MD5CryptoServiceProvider()).ComputeHash(originiv);
    //创建RijndaelManaged对象
    RijndaelManaged des=new RijndaelManaged();
    //定义将数据流链接到加密转换的流
    CryptoStream encrystream=new CryptoStream(outfile,des.CreateEncryptor(key,iv),CryptoStreamMode.Write);
    byte[] bin=new Byte[100];
    long infilelength=infile.Length;
    int dolength=0;
    int len;
    char cr=(char)13;
    Console.WriteLine("加密中...");
    //加密
    while (dolength<infilelength)
    {
    infile.Read(bin,0,100);
    len=bin.Length;
    encrystream.Write(bin,0,len);
    dolength=dolength+len;
    Console.Write(cr+"完成百分之"+(100*dolength/infilelength).ToString());
    }
    encrystream.Close();
    infile.Close();
    outfile.Close();
    //将密码保存到密文件中
    outfile=new FileStream(outfilename,FileMode.OpenOrCreate,FileAccess.Write);
    outfile.Position=outfile.Length;
    outfile.Write(key,0,key.Length);
    outfile.Close();
    }
    catch(Exception e)
    {
    Console.WriteLine(e.ToString());
    Console.ReadLine();
    }
    }
    }
    }
    这个例子演示了如何对上面的例子产生的密文件进行解密
    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    namespace ConsoleApplication3
    {
    class Class1
    {
    [STAThread]
    static void Main(string[] args)
    {
    Console.WriteLine("请输入需要解密的文件:");
    string infilename=Console.ReadLine();
    Console.WriteLine("请输入解密后文件保存的位置和文件名");
    string outfilename=Console.ReadLine();
    Console.WriteLine("请输入密码:");
    string originkey=Console.ReadLine();
    try
    {
    \\打开密文件
    FileStream infile=new FileStream(infilename,FileMode.Open);
    \\打开或创建解密文件
    FileStream outfile=new FileStream(outfilename,FileMode.OpenOrCreate);
    \\设置对称算法的初始化向量和取得密码和的哈希代码
    byte[] key=(new MD5CryptoServiceProvider()).ComputeHash((new UnicodeEncoding()).GetBytes(originkey));
    byte[] iv=(new MD5CryptoServiceProvider()).ComputeHash((new UnicodeEncoding()).GetBytes("abc"));
    \\检验输入的密码是否与密文件的密码一致
    bool checkpassword=false;
    int checkcount=0;
    bool pass=true;
    byte[] filekey=new byte[key.Length];
    infile.Seek(-16,SeekOrigin.End);
    infile.Read(filekey,0,filekey.Length);
    while (!checkpassword)
    {
    if (checkcount>5)
    {
    infile.Close();
    outfile.Close();
    return;
    }
    if (checkcount>0)
    {
    Console.WriteLine("密码不正确,请重新输入密码:");
    originkey=Console.ReadLine();
    key=(new MD5CryptoServiceProvider()).ComputeHash((new UnicodeEncoding()).GetBytes(originkey));
    }
    pass=true;
    int i=0;
    while (pass&&i<16)
    {
    if (filekey[i]!=key[i])
    pass=false;
    i++;
    }
    if (pass)
    checkpassword=true;
    checkcount++;
    }
    \\创建RijndaelManaged对象
    RijndaelManaged decryto=new RijndaelManaged();
    //定义将数据流链接到解密转换的流
    CryptoStream decrystream=new CryptoStream(outfile,decryto.CreateDecryptor(key,iv),CryptoStreamMode.Write);
    byte[] bin=new byte[100];
    long infilelength=infile.Length;
    int dolength=0;
    int len;
    char cr=(char)13;
    float persent;
    \\解密
    infile.Position=0;
    while (dolength<infilelength-16)
    {
    infile.Read(bin,0,100);
    len=bin.Length;
    decrystream.Write(bin,0,len);
    dolength=dolength+len;
    persent=100*dolength/infilelength;
    Console.Write(cr+"完成百分之"+persent.ToString());
    }
    decrystream.Close();
    infile.Close();
    outfile.Close();
    }
    catch (Exception e)
    {
    Console.WriteLine("错误信息:"+e.ToString());
    Console.ReadLine();
    }
    }
    }
    }
      

  2.   

    我估计错误在这里(没有测试过):
    CryptoStream CryptStream = new CryptoStream(stream,RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);你使用stream是原来字符串写入的数据流,这里你需要创建一个新流用来存储加密后的数据流(请参考msdn相关的例子),比如:
    MemoryStream stream_m=new MemoryStream();
    CryptoStream encrystream=new CryptoStream(stream_m,des.CreateEncryptor(key,iv),CryptoStreamMode.Write);
    byte[] b=new byte[SWriter.BaseStream.Length];
    SWriter.BaseStream.Read(b,0,b.Length);
    stream_m.Write(b,0,b.Length);
    StreamReader SReader = new StreamReader(stream_m);
    string readerPass =SReader.ReadToEnd();
    return readerPass;解密与上面同理。
      

  3.   

    即使原先的文件内容是合法的字符串,经过加密之后的Stream就不一定是合法的字符串了,而是一个Byte数组,所以读取加密Stream不能使用StreamReader/StreamWriter,而是用BinaryWriter/BinaryReader,然后再通过Encoding转换。
      

  4.   

    但是MSDN的例子中是用StreamReader/StreamWriter
    ms-elp://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconencryptingdata.htm
    是加密例子
    ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpcondecryptingdata.htm
    是解密例子
      

  5.   

    System.IO.MemoryStream stream=new MemoryStream();
    byte[] AddText=System.Text.UnicodeEncoding.Unicode.GetBytes(cipher);
    CryptoStream CryptStream = new CryptoStream(stream, RM.CreateEncryptor(EncryptedSymmetricKey,         EncryptedSymmetricIV),  CryptoStreamMode.Write);
    CryptStream.Write(AddText,0,AddText.Length);
    byte[] NewData=stream.ToArray();
    NewData的数量变少了!
    用FileStream加密解密都没问题,但用MemoryStream 就不知道为什么不可以!!!
      

  6.   

    不好意思,我对非对称加密和对称加密理解错误。我又看了一遍你给出msdn例子,我觉得原来的代码错误出在两个地方。第一点,流的操作总是从流当前位置开始的,而不是流的开始。第二点,正如知秋所说。
    我将你的代码改成了下面的代码,测试通过。
    public string WritePassWord(string PassWord)
    {
    System.IO.MemoryStream stream=new System.IO.MemoryStream();
              RijndaelManaged RMCrypto = new RijndaelManaged();
    byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
    byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
    StreamWriter SWriter = new StreamWriter(stream);
    SWriter.Write(PassWord);
             SWriter.Flush();
             stream.Position=0;
    CryptoStream CryptStream = new CryptoStream(stream, 
    RMCrypto.CreateEncryptor(Key, IV),   
    CryptoStreamMode.Read);
    byte[] b=new byte[100] ;
    MemoryStream m=new MemoryStream();
    int readLength=0;
    while ((readLength=CryptStream.Read(b,0,100))>0)
    {
    m.Write(b,0,readLength);
    readLength=0;
    }
             byte[] mb=new byte[m.Length];
    m.Position=0;
    m.Read(mb,0,mb.Length);
    string WritePass=System.Text.Encoding.Unicode.GetString(mb,0,mb.Length);
             stream.Close();
             CryptStream.Close();
             return WritePass;
        }
    public string ReaderPassWord(string PassWord)
    {
    System.IO.MemoryStream stream=new System.IO.MemoryStream();
    RijndaelManaged RMCrypto = new RijndaelManaged();
    byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
    byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
    byte[] mb=System.Text.Encoding.Unicode.GetBytes(PassWord);
    stream.Write(mb,0,mb.Length);
    stream.Position=0;
    CryptoStream CryptStream = new CryptoStream(stream, 
    RMCrypto.CreateDecryptor(Key, IV),   
    CryptoStreamMode.Read);
    StreamReader SReader = new StreamReader(CryptStream);
    string readerPass=SReader.ReadToEnd();
             stream.Close();
             CryptStream.Close();
             return readerPass;
    }