4

我正在尝试在 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();
}
4

3 回答 3

3

如果您正在处理 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();
于 2018-07-20T06:33:23.683 回答
3

从 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();
    }
}
于 2016-08-03T22:43:51.623 回答
1

看看下面的代码。在此示例中,私钥由 base64 编码字符串给出,并且还返回了 base64 编码字符串。注释的 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());
}
于 2016-06-12T09:39:01.887 回答