简体   繁体   English

充气城堡 ECDSA 从私钥创建公钥

[英]Bouncy Castle ECDSA Create Public Key from Private Key

I am trying to sign a bitcoin transaction in c#.我正在尝试用 C# 签署比特币交易。 I have 2 bits of code I am trying to complete.我有 2 位代码要完成。 I can create a set of private and public keys using Bouncy castle.我可以使用 Bouncy Castle 创建一组私钥和公钥。 I can convert this to wallet import format ok.我可以将其转换为钱包导入格式。

I can also generate a bitcoin address from the ECDSA public key.我还可以从 ECDSA 公钥生成比特币地址。

However, I want to sign a transaction and all I have is my private key.但是,我想签署一笔交易,而我所拥有的只是我的私钥。 I don't want to have to import into a wallet and sign.我不想必须导入钱包并签名。 So how can I generate the public key, given only the private key?那么如何生成公钥,只给出私钥呢?

I have found a javascript method that does this:我找到了一个这样做的javascript方法:

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

The only way I've seen in Bouncy Castle is to generate a random pair.我在 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();
}

From steininger's answer, I got the following to work with the sample keys I had.从 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();
    }
}

If you're dealing with DER encoded keys, it's even simpler:如果您正在处理 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();

take a look at the following code.看看下面的代码。 the private key is given by as base64 encoded string in this example and also a base64 encoded string is given back.在此示例中,私钥由 base64 编码字符串给出,并且还返回一个 base64 编码字符串。 the commented keyParameters are working, so use this one if you want to have key and curve.注释的 keyParameters 正在工作,所以如果你想要关键和曲线,请使用这个。

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());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM