Bouncy Castle ECDSA Создать открытый ключ из закрытого ключа

Я пытаюсь подписать биткойн-транзакцию на С #. У меня есть 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();
}

person user123976    schedule 25.02.2014    source источник


Ответы (3)


Из ответа Штайнингера я получил следующее для работы с имеющимися у меня образцами ключей.

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();
    }
}
person Ryan    schedule 03.08.2016

Если вы имеете дело с ключами в кодировке 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();
person Dylan Nicholson    schedule 20.07.2018

взгляните на следующий код. закрытый ключ задается как строка в кодировке 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());
}
person steininger    schedule 12.06.2016