zoukankan      html  css  js  c++  java
  • 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,经过测试比较稳定。
    签名

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    // 生成R=r*G
      TBCryptoBigInteger r = null;
      Random random = new SecureRandom();
      do // Generate r
      {
          r = new TBCryptoBigInteger(this.ecdomainpsCDKey.N.BitLength, random);
      }
      while (r.SignValue == 0);
      ECPoint R = this.ecdomainpsCDKey.G.Multiply(r);
    // Hash = SHA1(data,Rx,Ry)
    string hashStr = Sha1(31, rawKeyBytes, R.X.ToBigInteger().ToByteArray(), R.Y.ToBigInteger().ToByteArray());
    TBCryptoBigInteger hashInt = new TBCryptoBigInteger(hashStr, 2);
    // sig = r-Hash*D (mod n)
    TBCryptoBigInteger sig = r.Subtract(hashInt.Multiply(this.ecDCDKey)).Mod(this.ecdomainpsCDKey.N);


    验证

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    // 验证签名
      X9ECParameters ecps = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime256v1);
      ECPublicKeyParameters pk = new ECPublicKeyParameters("ECDSA",
          ecps.Curve.DecodePoint(Hex.Decode(KeyAttribute.GetKey(type.Assembly))),
          new ECDomainParameters(ecps.Curve, ecps.G, ecps.N, ecps.H));
      ISigner s = SignerUtilities.GetSigner("ECDSA");
      s.Init(false, pk);
      s.BlockUpdate(bytes, 0, dataLen);
      if (s.VerifySignature(sig))
    {
         this.data = new byte[dataLen];
         Array.Copy(bytes, 0, this.data, 0, data.Length);
    }
  • 相关阅读:
    关于32位操作系统和64位操作系统对InstallShield打包的影响
    NEWS: Symantec宣布Wise Package Studio将终止
    InstallShield 2012新功能试用(2) 调用MsiGetProperty等MSI API发生变化
    Basic INFO 在命令行Build InstallShield安装包工程获得压缩安装包
    NEWS InstallShield 2012 Service Pack 1发布
    Basic INFO InstallShield Basic MSI工程中如何在SetupCompleteSuccess界面中启动Readme
    Basic INFO InstallShield的脚本编辑器中如何显示代码行号
    Basic INFO 关于在InstallShield制作的安装包界面中删除InstallShield文字的厂商回复
    Basic INFO InstallShield工程中如何让产品的快捷方式名称始终与产品名保持一致
    Basic INFO: 创建隐藏文件夹
  • 原文地址:https://www.cnblogs.com/vaevvaev/p/6896772.html
Copyright © 2011-2022 走看看