本实例实现在网站会员注册时使用类的加密算法,加密会员信息的敏感数据将加密后的信息存储到数据库中。运行实例,填写会员信息如图17.13 所示。
单击“注册”按钮时将会员的敏感数据加密,然后将加密后的信息存储到数据库中,本实例加密了会员的密码、密码提示答案、E-mail 等敏感数据,加密后的数据如图17.14 所示。
关 键技术
不对称算法通常用于加密少量数据,如加密对称密钥和IV。通常执行不对称加密的个人使用由另一方生成的公钥。.NET Framework 为此目的而提供了RSACryptoServiceProvider 类,该类一些用于加密的方法及说明如表17.2 所示。
下在对比较重要的加密方法进行说明。
(1)Encrypt 方法
该方法使用RSA 算法对数据进行加密,语法如下:
public byte[] Encrypt (byte[] rgb,bool fOAEP)
参数说明
rgb:要加密的数据。
fOAEP:如果为true,则使用OAEP 填充(仅在运行Microsoft Windows XP 或更高版本的计算机上可用)执行直接的RSA 加密;
如果为false,则使用PKCS#1 1.5 版填充。
(2)ToXmlString方法
该方法用于创建并返回包含当前RSA 对象的密钥的 XML 字符串,语法如下:
public override string ToXmlString (bool includePrivateParameters)
参数说明
includePrivateParameters:true 表示同时包含RSA 公钥和私钥;false 表示仅包含公钥。
返回值:包含当前RSA 对象的密钥的XML 字符串。
设 计过程
自定义一个随机产生RSA类密钥的方法RSAKey(),此方法产生私钥和公钥,私钥用来解密数据,公钥用来加密数据,并将私钥和公钥分别存储在文件中,主要代码如下:
public void RSAKey()
{
try
{
System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string privatekey = rsa.ToXmlString(true);//产生公私密钥
string publickey = rsa.ToXmlString(false);//产生公有密钥
String path = Server.MapPath("key");//保存密钥文件夹
//将私有密钥保存在privatekey.txt 文件中
FileStream fsPrivate = File.Open(path + "/privatekey.txt", FileMode.Create, FileAccess.Write);
StreamWriter InPrivate = new StreamWriter(fsPrivate, UTF8Encoding.UTF8);
InPrivate.Write(privatekey);
InPrivate.Flush();
InPrivate.Close();
//将公有密钥保存在文件中
FileStream fsPublic = File.Open(path + "/publickey.txt", FileMode.Create, FileAccess.Write);
StreamWriter InPublic = new StreamWriter(fsPublic, UTF8Encoding.UTF8);
InPublic.Write(privatekey);
InPublic.Flush();
InPublic.Close();
}
catch (Exception ex)
{
throw new Exception("在产生密钥的时候出现错误!错误提示: \n" + ex.Message);
}
}
在初次加载程序时调用RSAKey()方法,为RSACryptoServiceProvider 类产生密钥,主要代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
RSAKey();
}
自定义一个方法RSAEncrypt(string m_strEncryptString),此方法用于加密字符串,从密钥文件中读取出公钥加密信息,然后返回加密后的字符串信息,主要代码如下:
public string RSAEncrypt(string m_strEncryptString)
{
try
{
byte[] PlainTextBArray; //定义存储加密字符串数组
byte[] CypherTextBArray; //定义存储加密后字符串数组
string Result;
System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//将公有密钥从publickey.txt 中读出来加密字符串
String path = Server.MapPath("key"); //保存密钥文件夹
//将私有密钥保存在文件中
StreamReader redKey = new StreamReader(path + "/publickey.txt", UTF8Encoding.UTF8);
rsa.FromXmlString(redKey.ReadToEnd()); //初始化密钥
redKey.Close();
PlainTextBArray = (new UnicodeEncoding()).GetBytes(m_strEncryptString); //把要加密的字符串转换成字节数组
CypherTextBArray = rsa.Encrypt(PlainTextBArray, false); //对字符串数组进行加密
Result = Convert.ToBase64String(CypherTextBArray); //显示加密信息
return Result;
}
catch (Exception ex)
{
throw new Exception("在加密的时候出现错误!错误提示: \n" + ex.Message);
}
}
自定义CheckUser()方法,此方法返回一个整数,判断用户名是否存在,主要代码如下:
public int CheckUser()
{
SqlConnection sqlconn = new SqlConnection("Server=(local);uid=sa;pwd=;database=db_Tome2");
int intCount = 0;
if (txtLoginName.Text == "")
{
Response.Write("");
}
else
{
string sqlstr = "select * from tb_04 where Name='" + this.txtLoginName.Text + "'";
sqlconn.Open();
SqlCommand sqlcom = new SqlCommand(sqlstr, sqlconn);
intCount = Convert.ToInt32(sqlcom.ExecuteScalar());
sqlconn.Close();
}
return intCount;
}
单击“检验”按钮,调用CheckUser()方法检验用户名是否已注册,主要代码如下:
protected void btnTest_Click(object sender, EventArgs e)
{
int intCount = CheckUser(); //调用方法检测用户名是否存在
if (intCount != 0)
{
Response.Write("");
return;
}
else
{
Response.Write("");
}
}
单击“注册”按钮,调用RSAEncrypt 方法将敏感信息加密后存储到数据库中,主要代码如下:
protected void Button2_Click(object sender, EventArgs e)
{
int intCount = CheckUser();//调用方法检测用户名是否存在
if (intCount != 0)
{
Response.Write("");
return;
}
//调用方法将注册信息加密
string sqlstr = "insert into tb_04 "
+ "values('" + txtLoginName.Text + "','" + ddlSex.SelectedValue
+ "','" + RSAEncrypt(txtPwd.Text.Trim()) + "','" + txtQuePwd.Text
+ "','" + RSAEncrypt(txtAnsPwd.Text.Trim()) + "','" + RSAEncrypt(txtEmail.Text.Trim()) + "')";
SqlConnection sqlconn = new SqlConnection("Server=(local);uid=sa;pwd=;database=db_Tome2;");
sqlconn.Open();
SqlCommand sqlcom = new SqlCommand(sqlstr, sqlconn);
sqlcom.ExecuteNonQuery();
sqlconn.Close();
Response.Write("");
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("");
}