ASP.NET 加密 Part.4(加密数据库中的敏感数据)
本章介绍如何创建一个简单的测试页面来加密存储在数据库表中的信息。这个表会被连接到一个在成员资格服务中注册的用户。不建议使用自定义 MembershipUser 实现一个支持额外属性的自定义的成员资格提供程序。不要太紧密的与你自己的逻辑结合,这样,你可以在多个成员资格提供程序中使用它。
创建一个数据库表来存储 MembershipUser 的额外信息。它通过 ProviderUserKey 连接到 MembershipUser,ProviderUserKey 意味着底层数据存储的主键:
create database ExtenderUser
go
use ExtenderUser
go
create table UserInfo
(
UserId uniqueidentifier primary key,
CreditCard varbinary(80),
street varchar(80),
ZipCode varchar(6),
City varchar(60)
)
不要为了额外的字段而创建一个自定义提供程序,建议只在支持成员资格服务的额外类型的数据存储时,才创建自定义提供程序。另外,比较敏感的信息是 CreditCard 字段,现在被存为了 varbinary 类型。
创建以下页面:
<form id="form1" runat="server">
<div>
<asp:LoginView runat="server" ID="MainLoginView">
<AnonymousTemplate>
<asp:Login runat="server" ID="MainLogin" />
</AnonymousTemplate>
<LoggedInTemplate>
Credit Card: <asp:TextBox runat="server" ID="txtCreditCard" /><br />
Street: <asp:TextBox runat="server" ID="txtStreet" /><br />
Zip Code: <asp:TextBox runat="server" ID="txtZipCode" /><br />
City: <asp:TextBox runat="server" ID="txtCity" /><br />
<asp:Button runat="server" ID="btnLoad" Text="Load" OnClick="btnLoad_Click" />
<asp:Button runat="server" ID="btnSave" Text="Save" OnClick="btnSave_Click" />
</LoggedInTemplate>
</asp:LoginView>
</div>
</form>
配置一下 web.config 的数据库连接字符串,接着就可以完成读写数据库的操作了,这些 ADO 代码没有什么特别之处,只是使用了之前创建的加密工具类:
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using EncryptionUtility;
using System.Configuration;
using System.Web.Security;
public partial class ExtenderUserInfo : System.Web.UI.Page
{
SqlConnection conn;
// We need some TextBox controls that we can find in the LoginView control
// template through FindControl() because they are only contained in a
// template of the LoginView.
private TextBox txtCreditCard;
private TextBox txtStreet;
private TextBox txtZipCode;
private TextBox txtCity;
// Used for storing the encryption key based on the code
// introduced previously with our SymmetricEncryptionUtility class.
private string encryptionKeyFile;
protected void Page_Load(object sender, EventArgs e)
{
encryptionKeyFile = Server.MapPath("Key.config");
SymmetricEncryptionUtility.AlgorithmName = "DES";
if (!System.IO.File.Exists(encryptionKeyFile))
{
SymmetricEncryptionUtility.GenerateKey(encryptionKeyFile);
}
conn = new SqlConnection(ConfigurationManager
.ConnectionStrings["ExtenderUser"].ConnectionString);
// Associate with Textfields
txtCreditCard = MainLoginView.FindControl("txtCreditCard") as TextBox;
txtStreet = MainLoginView.FindControl("txtStreet") as TextBox;
txtZipCode = MainLoginView.FindControl("txtZipCode") as TextBox;
txtCity = MainLoginView.FindControl("txtCity") as TextBox;
}
protected void btnSave_Click(object sender, EventArgs e)
{
conn.Open();
try
{
string sql = string.Format(@"update shopinfo set street=@street, zipcode=@zip,
city=@city, creditCard=@card where UserId=@key");
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@street", txtStreet.Text);
cmd.Parameters.AddWithValue("@zip", txtZipCode.Text);
cmd.Parameters.AddWithValue("@city", txtCity.Text);
// ProviderUserKey: 从用户的成员资格数据源获取用户标识符
cmd.Parameters.AddWithValue("@key", Membership.GetUser().ProviderUserKey);
// Now add the encrypted value
byte[] encryptedData = SymmetricEncryptionUtility
.EncryptData(txtCreditCard.Text, encryptionKeyFile);
cmd.Parameters.AddWithValue("@card", encryptedData);
int results = cmd.ExecuteNonQuery();
if (results == 0)
{
cmd.CommandText = "insert into shopinfo values(@key, @card, @street, @zip, @city)";
cmd.ExecuteNonQuery();
}
}
finally
{
conn.Close();
}
}
protected void btnLoad_Click(object sender, EventArgs e)
{
conn.Open();
try
{
string sql = "select * from shopinfo where userid=@key";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@key", Membership.GetUser().ProviderUserKey);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
txtStreet.Text = reader["street"].ToString();
txtZipCode.Text = reader["zipcode"].ToString();
txtCity.Text = reader["city"].ToString();
byte[] secretCard = reader["creditCard"] as byte[];
txtCreditCard.Text = SymmetricEncryptionUtility.DecryptData(secretCard, encryptionKeyFile);
}
}
}
finally
{
conn.Close();
}
}
}