橢圓曲線法在微軟安全保護CDKey的應用

xuniji123發表於2007-03-08

從Windows95起,Microsoft的產品安裝key從原來的10位數字改為25位字元,這一改動,代表著Microsoft告別了簡單的校驗和,從此投入了橢圓曲線法的懷抱。從密碼學的角度來看,這絕對是一個里程碑,因為當時橢圓曲線法仍在研究論證階段,Microsoft是第一個將之實用以商業產品的廠家。那麼在這25個字元裡到底有什麼呢?

1.Base24

這25個字元實際是114bits的資料用base24進行uucode後的結果,做為安裝key,這個base必須絕對避免誤認,所以Microsoft選擇了以下這24個字元做為uucode的base:bcdfghjkmpqrtvwxy2346789,所以,如果你的安裝key 有這24個字元以外的字元的話,你完全可以把它丟到垃圾筒裡去了━━不用試就知道它根本通不過了。

2.114 Bits

Uudecode後得到的114位按intel高位在後的格式表示如下:

   [ x xxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxx ] total 114 bits 
    | | |  55 bits sign 
    | |  28 bits hash 
    |  30 bits serial  31 bits data 
     1 bits flag /

flag:不明標誌,目前所見的各類key中這一位總是為0。

serial:使用者序列號,轉成十進位制表示為aaaabbbbbb,對應顯示為:

    零售版:xxxxx-aaa-bbbbbbx-xxxxx

    oem版: xxxxx-oem-0aaaabx-bbbbb
以上31bits總稱為data,是cdkey中的基本部分。

hash:data經特定處理得到的結果,見後文。

sign:hash值的橢圓曲線簽名,見後文。

3.橢圓曲線簽名演算法

要說明橢圓曲線簽名演算法可不是一件容易的事,有興趣的可以自己用“橢圓曲線”或是“elliptic curve”在搜尋引擎找相關的資料來看吧,這裡只簡單介紹Microsoft的用法。

所謂橢圓曲線是指這樣一類曲線方程:

y^2 + a1*xy + a3*y = x^3 + a2*x^2 + a4*x + a6

在密碼學裡用的是它的兩個特例,而Microsoft用的更是這兩個特例中的特例:

y^2 = x^3 + a*x + b ( mod p )

當a、b、p選定後,就可以確定一個橢圓曲線,再選擇一個生成點 g(gx,gy)。於是,存在一個最小的整數q使得q*g=o。然後,再任意選擇一個整數 kk(kx,ky)=k*g,這樣橢圓曲線簽名演算法的key就全生成了:

公開金鑰為:a,b,p,g(gx,gy),k(kx,ky)

私有金鑰為:a,b,p,g(gx,gy),q,k

要對data簽名時:

a.先任意選擇一個整數r;

b.將data、rx、ry共100個位元組求sha-1,取結果中的28位得到hash;

c.求sign = r - hash * k ( mod q );

d.把data、hash、sign三個陣列合後uucode得到25位cdkey。

驗證cdkey時:

a.把25位cdkey先uudecode再拆分後提到data、hash、sign;

b.求點r( rx, ry ) = sing * g + hash * k ( mod p );

c.將data、rx、ry共100個位元組求sha-1,取結果中的28位得到hash';

d.如果hash = hash',則該cdkey為有效key。

4.Bink

從前面的說明可以看出,為了驗證cdkey,Microsoft 必須公開橢圓曲線簽名演算法中的公開金鑰,那麼這個公開金鑰放在哪裡呢?答案是在pidgen.dll裡的bink資源裡(其他產品如office則被包在*.msi),而且一共有兩組,從目前已知的key組合來看,第一組金鑰是用以零售版本的,第二組則用於oem版本。兩個產品的key能否通用就在於對應的金鑰是否相同,比如中文版的Windows 2000的pro/srv/advsrv的第二組金鑰也是相同的,即一個PWindows 2000 pro的oem版的key,可同時供 PWindows 2000 srv/adv的oem版使用。

5.破解及其難度

要破解cdkey的生成演算法,必須從Microsoft 公開的金鑰中求出對應的私有金鑰,即只要求出q和k即可。從bink中公開的金鑰來看,p 是一個384 bits的質數,看起來計算量好象至少要o(2^168)才行,但Microsoft設計中一個缺陷(?)使實際工作量降低到只有o(2^28)就可以了。

為什麼相差這麼遠?

回頭看看3.c中的式子:

sign = r - hash * k ( mod q )

通常情況下q可以是很大的值,因此sign應該也很大,但Microsoft 為了減少使用者輸入的cdkey的數量,把sign的值限死在55 bits,因此,自然也限定了q最多也不能超過56 bits。依此類推,由於k在一臺賽揚ii 800的機器上只用6個小時就解出某組金鑰的q值,最多時在一臺雷鳥1g上用了28個小時才算出另一組金鑰的k值,其他平均大約都在十個小時左右就可以求出。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8271432/viewspace-903437/,如需轉載,請註明出處,否則將追究法律責任。

相關文章