从私钥生成scep256k1公钥

时间:2019-12-02 12:24:14

标签: java bouncycastle bitcoin

我想使用bouncycastle指定32bytes的私钥来生成与secp256k1对应的公钥,但是我只看到bouncycastle直接生成密钥对。我需要知道椭圆曲线的基点G。如何修改此代码以实现它?

private static ECKeyPair create(KeyPair keyPair) {
        BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate();
        BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic();
        BigInteger privateKeyVal = privateKey.getD();

        byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
        BigInteger publicKeyVal = new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length));

        return new ECKeyPair(privateKeyVal, publicKeyVal);
    }
    public static ECKeyPair createECKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException {
        //Add bouncy castle as key pair gen provider
        Security.addProvider(new BouncyCastleProvider());
        //Generate key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC");
        ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1");
        keyPairGenerator.initialize(ecGenParameterSpec, new SecureRandom());
        //Convert KeyPair to ECKeyPair, to store keys as BigIntegers
        return ECKeyPair.create(keyPairGenerator.generateKeyPair());
    }

1 个答案:

答案 0 :(得分:0)

您可能正在使用web3j,因为您的create方法属于org.web3j.crypto.ECKeyPair。此类为您的目的提供了适当的create重载,这些原始重载期望原始私钥为BigInteger或字节数组(后者需要web3j utilitiy classes以及web3j的字节数组) :

import org.web3j.crypto.ECKeyPair;
import java.math.BigInteger;
...
byte[] privateKey = hexStringToByteArray("a1e3ce382dafebc4ed9a9efc7d771f669745e2a88b33f2b5eb4efa8c47721346"); // e.g. from //kjur.github.io/jsrsasign/sample/sample-ecdsa.html
ECKeyPair ec =  ECKeyPair.create(new BigInteger(1, privateKey));
//ECKeyPair ec =  ECKeyPair.create(privateKey); // needs web3j utilitiy classes
System.out.println("Raw private key: " + ec.getPrivateKey().toString(16));
System.out.println("Raw public  key: " + ec.getPublicKey().toString(16));

由于ECKeyPair是为Secp256k1实现的,因此无需指定曲线参数。请注意,web3j在后台需要BouncyCastle(尽管在上面的代码中未明确使用它)。在示例中,为简单起见(here),我从十六进制字符串创建了字节数组。