首先,都知道一个字节(byte)等于八位二进制数。在数据表中将密码字段设置为binary类型,再结合哈希散列运算可以实现密码加密。
下面介绍下binary 和 varbinary:
binary 和 varbinary
固定长度 (binary) 的或可变长度 (varbinary) 的 binary 数据类型。
binary [ ( n ) ]
固定长度的 n 个字节二进制数据。N 必须从 1 到 8,000。存储空间大小为 n+4 字节。
varbinary [ ( n ) ]
n 个字节变长二进制数据。n 必须从 1 到 8,000。存储空间大小为实际输入数据长度 +4 个字节,而不是 n 个字节。输入的数据长度可能为 0 字节。在 SQL-92 中 varbinary 的同义词为 binary varying。
注释
如果在数据定义或变量声明语句中没有指定 n,默认长度为 1。如果没有用 CAST 函数指定 n,默认长度为 30。
当列数据项大小一致时应使用 binary。
当列数据项大小不一致时应使用 varbinary。
接下来说明实现方法:
密码子段类型为binary(50)。应用System Security.Cryptography名称空间下的SHA1类的ComputeHash()方法将字符密码进行哈希散列运算转换为byte[]类型对象,保存入数据库。
实例代码:
1 //哈系散列转换 2 public byte[] getSaltedPassword(string password) 3 { 4 SHA1 sha1=SHA1.Create(); 5 //应用System.Text空间下的Unicode.GetBytes方法获得byte. 6 byte[] bytePassword=sha1.ComputeHash(Encoding.Unicode.GetBytes(password)); 7 return bytePassword; 8 }
1 //数据存入,直接将byte[]保存入binary字段 2 public int AccountRegister(string accountName,string password,string email) 3 { 4 byte[] bytePassword = this.getSaltedPassword(password); 5 SqlConnection myConnection = new SqlConnection(this.GetConnStr); 6 myConnection.Open(); 7 SqlCommand myCommand = new SqlCommand("Account_Add",myConnection); 8 myCommand.CommandType=CommandType.StoredProcedure; 9 SqlParameter prmAccountName=myCommand.Parameters.Add(new SqlParameter("@AccountName",SqlDbType.VarChar,50)); 10 prmAccountName.Value=accountName; 11 SqlParameter prmPassword=myCommand.Parameters.Add(new SqlParameter("@password",SqlDbType.Binary,50)); 12 prmPassword.Value=bytePassword; 13 SqlParameter prmEmail=myCommand.Parameters.Add(new SqlParameter("@email",SqlDbType.VarChar,50)); 14 prmEmail.Value=email; 15 int myInt=myCommand.ExecuteNonQuery(); 16 myCommand.Dispose(); 17 myConnection.Close(); 18 return myInt; 19 }
1 //密码比较。将字符密码转换为哈西散列后直接与数据库binary密码字段比较 2 public int AccountVerify(string accountName,string password) 3 { 4 byte[] bytePassword = this.getSaltedPassword(password); 5 SqlConnection myConnection = new SqlConnection(this.GetConnStr); 6 myConnection.Open(); 7 SqlCommand myCommand = new SqlCommand("Account_Check",myConnection); 8 myCommand.CommandType=CommandType.StoredProcedure; 9 SqlParameter prmAccountName=myCommand.Parameters.Add(new SqlParameter("@AccountName",SqlDbType.VarChar,50)); 10 prmAccountName.Value=accountName; 11 SqlParameter prmPassword=myCommand.Parameters.Add(new SqlParameter("@password",SqlDbType.Binary,50)); 12 prmPassword.Value=bytePassword; 13 SqlParameter prmReturnValue=myCommand.Parameters.Add(new SqlParameter("@Return_Value",SqlDbType.Int,4)); 14 prmReturnValue.Direction=ParameterDirection.ReturnValue; 15 myCommand.ExecuteNonQuery(); 16 int accountID=(int)prmReturnValue.Value; 17 myCommand.Dispose(); 18 myConnection.Close(); 19 return accountID; 20 }
//相关存储过程(Store procedure)
1 //登陆验证 2 CREATE PROCEDURE Account_Check @AccountName varchar(50),@Password binary(50) 3 AS 4 Declare @AccountId int; 5 Select @AccountId= AccountID From Accounts 6 Where accountName=@accountname; 7 If isnull(@AccountID,0)=0 8 Select @AccountId= -1; --//账号错误! 9 Else 10 Begin 11 Select @accountID=null 12 Select @AccountId= AccountID From Accounts 13 Where accountName=@accountname and password=@password; 14 If isnull(@AccountID,0)=0 15 Select @AccountID=0; --//密码错误! 16 End 17 Return @AccountID;
1 //用户增加 2 CREATE PROCEDURE Account_Add @accountName varchar(50),@password binary (50),@email varchar(50) 3 AS 4 insert into Accounts(accountName,password,email) 5 values(@accountName,@password,@email); 6 return @@Error;