S?Q?L? ?S?e?r?v?e?r?中??的?P?W?D?E?N?C?R?Y?P?T?与?P?W?D?C?O?M?P?A?R?E?函?数

前幾天有個客戶的網站出問題(不是我們開發的),請我們幫他看,主要的問題是他們的網站會員在進行查詢密碼時,會員收到信的時候在密碼的欄位竟然會出現 System.Binary[] 字樣。而我進去資料庫中查看時,發現該會員資料表中的密碼欄位是 varbinary 格式,而我當然不知道他儲存的是什麼值,進而查看他們資料庫中的 Stored Procedure 對於密碼欄位的操作方法,這才發現他們用來驗證會員是否正確登入的方法是使用 PWDCOMPARE 函數。

由於我沒看過這個函數,便上網去查看看,發現這個函數真的是個迷樣的 SQL 內建 Function,而且在 MSDN, TechNet 上都查不到相關文件,而我在 Google 搜尋 pwdcompare site:microsoft.com 得到的結果也僅僅才 127 筆資料而已,且大多這個關鍵字僅僅出現在論壇中,感覺這個 Function 似乎是微軟刻意不讓他曝光的。

而 PWDENCRYPT 與 PWDCOMPARE 函數剛好是一對兄弟,一個負責加密、一個負責比對,但就是沒有「解密」的函數。意思也就是說,使用 PWDENCRYPT 加密過的資料是無法反解的,類似一種 Hash 處理方法。

而且我還發現,使用 PWDENCRYPT 函數加密同樣的字串資料,每次回應的結果都會不一樣,但是使用 PWDCOMPARE 函數一樣可以對加密過的資料進行比對,以下是簡單的使用方法介紹。

PWDENCRYPT 函數

select pwdencrypt(‘ok‘) 

執行後的結果:

0x010066E6CDE3C8DE9363BE015AC22966456F230432D6485C6B58 

注意:每次執行 select pwdencrypt(‘ok‘) 的結果都會不一樣,這是一種對密碼保護的機制,只是我不清楚他的演算法。
 
PWDCOMPARE 函數 

select pwdcompare(‘ok‘, 0x010066E6CDE3C8DE9363BE015AC22966456F230432D6485C6B58)   

執行後的結果為 1 或 0 而已,1 代表密碼比對成功,0 代表密碼比對失敗。

第一個參數是當初加密時的設定的密碼字串。第二個參數是當時加密後的二進位值。  事實上,SQL Server 本身在進行密碼驗證時,應該也就是用 PWDCOMPARE 函數
在比對的,怎麼說呢?你可以先執行以下 T-SQL 查詢出系統登入帳號的 password_hash 欄位:

SELECT password_hash FROM master.sys.sql_logins WHERE name=‘sa‘  

然後再將結果用 PWDCOMPARE 函數驗證一下你設定的 sa 密碼,如果回傳值是 1 就代表密碼正確。
 
備註:雖然有人說這類 undocumented functions 未來可能隨時被取消或刪除,但我卻認為這一組 Function 應該會長久存在,只是「沒有文件」而已。
 
我也簡單的測試了一下,這兩個 Function 在 SQL 2000, 2005, 2008 都可以使用,只是我也發現了一些不同的 SQL Server 版本之間在使用這兩個
 Function 時的小差異:

1. 使用 PWDENCRYPT 時 SQL 2000 與 SQL 2005/2008 加密過後的 hash 長度不一樣!
 
2. SQL 2005/2008 加密過的密碼在 SQL 2000 中無法使用 PWDCOMPARE 函數 驗證密碼!
 
3. SQL 2005 與 SQL 2008 基本上是相容的。
 
4. SQL 2000 加密過的密碼雖然比較長,但在 SQL 2005/2008 中還是可以使 用 PWDCOMPARE 函數驗證密碼!

要使用這兩個 Function 的人可能要小心的不是 PWDENCRYPT 與 PWDCOMPARE 函數未來會消失,而是要考慮未來的 SQL Server 版本對兩個 Function 的實做是否能相容,目前看來向下相容應該是沒問題,但未來是否會持續向下相容還是很難說,畢竟資料庫中的資料還是會一直沿用下去。

转自:

http://blog.miniasp.com/post/2008/12/SQL-Server-secret-PWDENCRYPT-and-PWDCOMPARE-function.aspx

S?Q?L? ?S?e?r?v?e?r?中??的?P?W?D?E?N?C?R?Y?P?T?与?P?W?D?C?O?M?P?A?R?E?函?数

时间: 2024-08-07 08:40:16

S?Q?L? ?S?e?r?v?e?r?中??的?P?W?D?E?N?C?R?Y?P?T?与?P?W?D?C?O?M?P?A?R?E?函?数的相关文章

s?q?l?s?e?r?v?e?r?结?果?集?转?为?字?符?串

比如有语句select username from Employee 返回结果是: username 张三 李四 王五 怎么输出一个字符串类似: 张三,李四,王五 答: declare @s varchar(1000) select @s=isnull(@s+',','')+username from Employee select @s as username --> 生成测试数据表:Employee   IF NOT OBJECT_ID('[Employee]') IS NULL     D

执?行?o?r?a?c?l?e?函?数?的?四?种?方?法

1.在定义函数时:如果有参数,则参数可有类型但是不加长度. 2.在执行函数: var/variable var_name var_type(如果数据类型是number则没有长度,如果数据类型是varchar2,则可以写长度)                      call(此处不能用exec) 函数名(参数) into :var_name;                举例:         SQL>var dd varchar2          SQL>call get_sal(77

P?H?P? ?5?.?3?连?接?s?q?l? ?s?e?r?v?e?r? ?2?0?0?8? ?R?2

我的机器为: xp sp3 sql server 2008 developer apache 2.2.2 php 5.3  从5.3开始,php就不再提供mssql.dll了,所以要php连接sql server 2008/2012必须要使用微软提供的sql server for php 2.0/3.0了. 有必要提醒一下,php5.4必须要3.0和Microsoft SQL Server 2012 Native Client. php官方帮助 http://php.net/manual/zh/

s?q?l? ?s?e?r?v?e?r? ?2?0?0?0?登?录?名?与?数?据?库?用?户?名?的?关?联?问?题

MS SQL Server 2000 数据库使用备份还原造成的孤立用户和对象名'xxx'无效的错误的解决办法     在使用数据库的过程中,经常会遇到数据库迁移或者数据迁移的问题,或者有突然的数据库损坏,这时需要从数据库的备份中直接恢复.但是,此时会出现问题,这里说明几种常见问题的解决方法.  一.孤立用户的问题比如,以前的数据库的很多表是用户test建立的,但是当我们恢复数据库后,test用户此时就成了孤立用户,没有与之对应的登陆用户名,哪怕你建立了一个test登录用户名,而且是以前的用户密码

《C++编程思想》第八章 内 联 函 数 (知识点+习题+解答)

一.相关知识点 任何在类中定义的函数自动地成为内联函数,但也可以使用inline关键字放在类外定义的函数前面使之成为内联函数.但为了使之有效,必须使函数体和声明结合在一起,否则,编译器将它作为普通函数对待.因此 inline int PlusOne(int x); 没有任何效果,仅仅只是声明函数(这不一定能够在稍后某个时候得到一个内联定义).成功的方法如下: inline int PlusOne(int x) { return ++x ;} 在头文件里,内联函数默认为内部连接--即它是 stat

S?Q?L?获?取?当?前?时?间?(?日?期?)

--获取当前日期(如:yyyymmdd) select CONVERT (nvarchar(12),GETDATE(),112) --获取当前日期(如:yyyymmdd hh:MM:ss) select GETDATE() --获取当前日期(如:yyyy-mm-dd) Select Datename(year,GetDate())+'-'+Datename(month,GetDate())+'-'+Datename(day,GetDate()) --获取当前日期(如:yyyy/mm/dd) se

详解使用w?s?g?e?n?和?w?s?i?m?p?o?r?t?开?发?W?e?b?S?e?r?v?i?c?e

本文旨在描述如何使用jdk自带的wsgen.exe 和wsimport.exe开发WebService. 1.新建一个java工程,项目名:WebServiceDemo.由于本文想通过完全手动建立的方式来演示整个过程,故我们的工程目录就是WebServiceDemo啦! 2.在此目录下新建Business.java 和 BusinessImpl.java两个类,分别如下: public interface Business { public String echo(String message)

W?i?n?下?h?t?t?p?d?+?p?h?p?+?m?y?s?q?l?环?境?集?成

apache+php+mysql: php下载:  VC6就是legacy Visual Studio 6 compiler,就是使用这个编译器编译的,  VC9就是the Visual Studio 2008 compiler,就是用微软的VS编辑器编译的  如果你选用的是Apache或者其他服务软件,那么选择VC6,选用的是IIS的话,那么请下载VC9的.  Thread Safe 是线程安全,  Non Thread Safe就是非线程安全,   官方并不建议你将Non Thread Sa

C?#? ?读?写?S?Q?L?数?据?库?I?m?a?g?e?字?段

数据库的Image字段保存的是字节,所以写入数据库Image字段和从数据库Image字段读取的内容都应该为字节. 1.数据库Image字段读写文件      写文件:写文件的过程为将文件以流文件形式打开并将内容读取到一个byte数组,然后将此byte数组写入数据库的Image字段. 源码:     FileInfo finfo=new FileInfo("文件名");   //绝对路径 if(finfo.Exists) {         SqlConnection conn=new