程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> c#使用橢圓簽名算法制作軟件序列號

c#使用橢圓簽名算法制作軟件序列號

編輯:關於C#

橢圓曲線密碼學(Elliptic curve cryptography,縮寫為ECC)是基於橢圓曲線數學的一 種公鑰密碼的方法。橢圓曲線在密碼學中的使用是在1985年由Neal Koblitz和Victor Miller 分別獨立提出的。

橢圓簽名算法應該是微軟最先用在軟件保護上的,我們平常用的25位序列號就是基於橢圓 簽名算法的。理論上說,橢圓簽名算法是很難破解的,因為...(省略,感興趣的可以看看《 ECC加密算法入門介紹》這篇文章)。但是因為微軟出於序列號長度的考慮,簽名的長度只有 62bit(具體是多少,忘了),所以可以暴力計算私鑰。我們用過的算號器就是這樣的。

定義:

橢圓曲線Ep=(p,a,b,G,n,h)

p、a、b 用來確定曲線,G為基點,n為點G的階,h是橢圓曲線上所有點的個數m與n相除的 整數部分

簽名過程

1,選擇一條橢圓曲線Ep(a,b),和基點G

2,選擇私有密鑰k(k<n,n為G的階),利用基點G計算公開密鑰K=kG

3,取一個隨機整數r(r<n),計算點R=rG

4,計算特征信息和R的散列值,即Hash=SHA(data,x,y)

5,計算sig≡r-Hash*k(mod n)

6,使用sig和Hash生成序列號(例如使用BASE24編碼)

驗證過程

1,從序列號中提取sig和Hash

2,計算R≡sig*G+Hash*K (mod p)

3,計算計算特征信息和R的散列值,即H=SHA(data,x,y)

4,比較H和Hash

實際上,上述過程就是Elliptic Curve DSA (ECDSA)。

好吧,言歸正傳,我們如何在c#中使用橢圓簽名算法呢?

在.Net3.5中,微軟提供了ECDsaCng類,但是局限性是必須在Vista系統上才能使用,另外 就是微軟的實現事先為我們確定了橢圓曲線的參數(ECDsaP256,ECDsaP384,ECDsaP521),我 們沒有辦法使用自己的參數。關於ECDsaCng類的使用,已經有人做了介紹,MSDN裡也有說明 。這裡我要說的是如何使用第三方類庫。

這裡介紹的第三方加密類庫是BCCCrypto(http://www.bouncycastle.org/csharp/),現在 的版本是1.4,經過測試比較穩定。

簽名

1 // 生成R=r*G
2 TBCryptoBigInteger r = null;
3 Random random = new SecureRandom();
4 do // Generate r
5 {
6     r = new TBCryptoBigInteger(this.ecdomainpsCDKey.N.BitLength, random);
7 }
8 while (r.SignValue == 0);
9 ECPoint R = this.ecdomainpsCDKey.G.Multiply (r);
10 // Hash = SHA1(data,Rx,Ry)
11 string hashStr = Sha1(31, rawKeyBytes, R.X.ToBigInteger().ToByteArray(), R.Y.ToBigInteger().ToByteArray ());
12 TBCryptoBigInteger hashInt = new TBCryptoBigInteger(hashStr, 2);
13 // sig = r-Hash*D (mod n)
14 TBCryptoBigInteger sig = r.Subtract (hashInt.Multiply(this.ecDCDKey)).Mod(this.ecdomainpsCDKey.N);

驗證

1 // 驗證簽名
2 X9ECParameters ecps = X962NamedCurves.GetByOid (X9ObjectIdentifiers.Prime256v1);
3 ECPublicKeyParameters pk = new ECPublicKeyParameters("ECDSA",
4     ecps.Curve.DecodePoint (Hex.Decode(KeyAttribute.GetKey(type.Assembly))),
5     new ECDomainParameters(ecps.Curve, ecps.G, ecps.N, ecps.H));
6 ISigner s = SignerUtilities.GetSigner("ECDSA");
7 s.Init(false, pk);
8 s.BlockUpdate(bytes, 0, dataLen);
9 if (s.VerifySignature(sig))
10 {
11     this.data = new byte[dataLen];
12     Array.Copy(bytes, 0, this.data, 0, data.Length);
13 }

另外,關於BASE24,大整數,大家可以看看園子裡的文章。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved