1. 程式人生 > >國家商用password(五)基於SM2的軟件授權碼生成及校驗

國家商用password(五)基於SM2的軟件授權碼生成及校驗

clas 信息 ecp register 方法 序列號 mod 生成 pub

將公開密鑰算法作為軟件註冊算法的優點是Cracker非常難通過跟蹤驗證算法得到註冊機。以下。將介紹使用SM2國密算法進行軟件註冊的方法。

生成授權碼

  1. 選擇SM2橢圓曲線參數(P,a,b,N,Gx,Gy)
  2. 用隨機數發生器產生隨機數r∈[1,n-1]
  3. 計算橢圓曲線點R=[r]G=(XR,YR)
  4. 計算哈希值h=SM3(username ∥ XR ∥ YR)
  5. 計算序列號s≡(r - h * d) mod N。當中d為私鑰,N為G點的階
  6. 將s和h一起作為用戶的授權碼
校驗授權碼
  1. 確定SM2橢圓曲線參數(P,a,b,N,Gx,Gy)
  2. 提取序列號s和哈希值h
  3. 計算點R≡([s]G + [h]Q) mod P。當中Q為公鑰。P為素域元素數目
  4. 計算哈希值h‘=SM3(username ∥ XR ∥ YR)
  5. 假設h‘=h 則註冊成功;假設h‘≠h。則註冊失敗

在國家商用password算法開放動態庫OpenSM.dll的SM2類中已集成授權碼的生成和驗證方法。

相應的成員函數為:

/// <summary>
/// 生成授權碼
/// </summary>
/// <param name="userId">用戶註冊信息</param>
/// <param name="PrivateKey">私鑰</param>
/// <returns>授權碼</returns>   
/// <remarks>註意:對於同樣的註冊信息。每次生成的授權碼並不同樣</remarks>
public ECLicenseKey LicenseKeyMaker(byte[] userId, BigInteger PrivateKey);

/// <summary>
/// 生成授權碼
/// </summary>
/// <param name="userId">用戶註冊信息</param>
/// <param name="PrivateKey">私鑰</param>
/// <param name="r">隨機數。其值在[1, N-1]。N為G點的階</param>
/// <returns>授權碼</returns>
/// <remarks>註意:對於同樣的註冊信息和同樣的r。每次生成的授權碼一致</remarks>
public ECLicenseKey LicenseKeyMaker(byte[] userId, BigInteger PrivateKey, BigInteger r);

/// <summary>
/// 校驗授權碼
/// </summary>
/// <param name="userId">用戶註冊信息</param>
/// <param name="RegisterCode">註冊碼</param>
/// <param name="PublicKey">公鑰</param>
/// <returns>
///     true:校驗通過
///     fasle:校驗失敗
/// </returns>
public bool LicenseKeyVerifier(byte[] userId, ECLicenseKey RegisterCode, ECPoint PublicKey);

ECLicenseKey類定義例如以下:
/// <summary>
/// SM2password算法註冊機生成授權碼格式
/// </summary>
public class ECLicenseKey
{
 public readonly BigInteger mKey;
 public readonly BigInteger mHash;

 /// <summary>
 /// 構造函數
 /// </summary>
 /// <param name="key">授權碼</param>
 /// <param name="hash">哈希值</param>
 public ECLicenseKey(BigInteger key, BigInteger hash)
 {
  this.mKey = key;
  this.mHash = hash;
 }
}


??

國家商用password(五)基於SM2的軟件授權碼生成及校驗