对称加密同解密的问题!!! .net中不是有加密且可以解密的类吗?用它就得了!System.security.cryptography命令空间下! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这是我以前写的程序,和你的代码的功能差不多,测试通过。这个例子演示了如何使用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();}}}} 我估计错误在这里(没有测试过):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;解密与上面同理。 即使原先的文件内容是合法的字符串,经过加密之后的Stream就不一定是合法的字符串了,而是一个Byte数组,所以读取加密Stream不能使用StreamReader/StreamWriter,而是用BinaryWriter/BinaryReader,然后再通过Encoding转换。 但是MSDN的例子中是用StreamReader/StreamWriterms-elp://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconencryptingdata.htm是加密例子ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpcondecryptingdata.htm是解密例子 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 就不知道为什么不可以!!! 不好意思,我对非对称加密和对称加密理解错误。我又看了一遍你给出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; } 数据项多列填充表格 求捕获某网页某已知ID的texboxt的value........ SQL SERVER 2005 定义函数的问题 [非常急]vss为什么签进去的项目文件(*.sln)打不开? sql server全文检索的问题 关于日期比较得问题---谢谢 xml文件导入datatable GetWindowText获取标题问题 .net被我安在D盘,D盘下有一个WINNT目录被我删了,.NET就起不来了,我的系统在C盘 上传附件的问题啊,有没有谁做过上传附件的例子啊,给分哟,急哟 C#可以写DLL、EXE文件吗?它是不是只用来开发ASP.NET? 何如用用c#做登陆界面?
这个例子演示了如何使用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();
}
}
}
}
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;解密与上面同理。
ms-elp://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconencryptingdata.htm
是加密例子
ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpcondecryptingdata.htm
是解密例子
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 就不知道为什么不可以!!!
我将你的代码改成了下面的代码,测试通过。
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;
}