首先,都知道一個字節(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;