【问题标题】:Bouncy Castle ECDSA Create Public Key from Private KeyBouncy Castle ECDSA 从私钥创建公钥
【发布时间】:2014-02-25 02:27:17
【问题描述】:

我正在尝试在 c# 中签署比特币交易。我有 2 位代码要完成。我可以使用 Bouncy castle 创建一组私钥和公钥。我可以把它转换成钱包导入格式。

我还可以从 ECDSA 公钥生成比特币地址。

但是,我想签署一笔交易,而我所拥有的只是我的私钥。我不想导入钱包并签名。那么如何生成公钥,只给私钥呢?

我找到了一个可以做到这一点的 javascript 方法:

ecparams.getG().multiply(this.priv).getEncoded();

我在 Bouncy Castle 中看到的唯一方法是生成一个随机对。

private static AsymmetricCipherKeyPair GenerateKeys(int keySize)
{
  ECKeyPairGenerator gen = new ECKeyPairGenerator();
  SecureRandom secureRandom = new SecureRandom();
  KeyGenerationParameters keyGenParam = new KeyGenerationParameters(secureRandom, keySize);
  gen.Init(keyGenParam);
  return gen.GenerateKeyPair();
}

【问题讨论】:

    标签: c# bouncycastle bitcoin ecdsa


    【解决方案1】:

    如果您要处理 DER 编码的密钥,那就更简单了:

      var privateKey = PrivateKeyFactory.CreateKey(bytes) as ECPrivateKeyParameters;
      if (privateKey == null)
           return null;
      Org.BouncyCastle.Math.EC.ECPoint q = privateKey.Parameters.G.Multiply(privateKey.D);
      var publicParams = new ECPublicKeyParameters(privateKey.AlgorithmName, q, privateKey.PublicKeyParamSet);
      return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicParams).GetDerEncoded();
    

    【讨论】:

      【解决方案2】:

      从 steininger 的回答中,我得到了以下内容来使用我拥有的示例键。

      using Org.BouncyCastle.Asn1.Sec;
      using Org.BouncyCastle.Asn1.X9;
      using Org.BouncyCastle.Crypto.Parameters;
      using Org.BouncyCastle.Math;
      using Org.BouncyCastle.Math.EC;
      
      public static class Example
      {
          private static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
          private static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
      
          public static byte[] ToPublicKey(byte[] privateKey)
          {
              BigInteger d = new BigInteger(privateKey);
              ECPoint q = domain.G.Multiply(d);
      
              var publicParams = new ECPublicKeyParameters(q, domain);
              return publicParams.Q.GetEncoded();
          }
      }
      

      【讨论】:

        【解决方案3】:

        看看下面的代码。在此示例中,私钥由 base64 编码字符串给出,并且还返回了 base64 编码字符串。注释的 keyParameters 正在工作,所以如果你想拥有 key 和 curve,请使用这个。

        private static readonly Org.BouncyCastle.Asn1.X9.X9ECParameters curve = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256r1");
        private static readonly Org.BouncyCastle.Crypto.Parameters.ECDomainParameters domain = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
        public string GetPublicKey(string privKey)
        {
              Org.BouncyCastle.Math.BigInteger d = new Org.BouncyCastle.Math.BigInteger(Convert.FromBase64String(privKey));
              //var privKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters(d, domain);
              Org.BouncyCastle.Math.EC.ECPoint q = domain.G.Multiply(d);
              //var pubKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters(q, domain);
              return Convert.ToBase64String(q.GetEncoded());
        }
        

        【讨论】: