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);
    }
  • 相关阅读:
    [Spark]Spark-streaming通过Receiver方式实时消费Kafka流程(Yarn-cluster)
    [git]将代码上传到github
    [Scala]Scala安装以及在IDEA中配置Scala
    [tesseract-ocr]OCR图像识别Ubuntu下环境包安装
    [Spark]Spark-sql与hive连接配置
    [py2neo]Ubuntu14 安装py2neo失败问题解决
    [wcp部署]Linux(Ubuntu)安装部署WCP
    Office 365入门教程(一):开始使用Office 365
    微软Power BI入门教程(一):认识Power BI
    电脑病毒猛于虎,但这些坏习惯猛于病毒
  • 原文地址:https://www.cnblogs.com/vaevvaev/p/6896772.html
Copyright © 2011-2022 走看看