如何制作充气城堡ECPublicKey [英] How to make a Bouncy Castle ECPublicKey

查看:84
本文介绍了如何制作充气城堡ECPublicKey的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道EC公钥的曲线名称( secp256k1 )和 X Y 坐标.

I know the curve name (secp256k1) and the X and Y coordinates of the EC public key.

如何从其中制作一个 org.bouncycastle.jce.interfaces.ECPublicKey ?

我已阅读 https://stackoverflow.com/a/29355749/5453873 ,但其中的代码使用 java.security ... 而不是 org.bouncycastle ... ,而ECPublicKey是 org.bouncycastle ... 中的接口,不是可实例化的类

I've read https://stackoverflow.com/a/29355749/5453873 but the code there uses java.security... instead of org.bouncycastle... and ECPublicKey is an interface in org.bouncycastle... not an instantiable class.

推荐答案

使用Bouncy Castle生成ECPublicKey

这将生成JCE/JCA中使用的EC公共密钥.有弹性的城堡提供程序可以直接使用这些软件密钥.否则,Bouncy仅用于生成生成公钥所需的参数.

Generating ECPublicKey using Bouncy Castle

This generates the EC public key as used in the JCE/JCA. The Bouncy Castle provider can directly use these software keys. Otherwise Bouncy is just used to generate the parameters required to generate the public key.

package nl.owlstead.stackoverflow;

import static java.nio.charset.StandardCharsets.US_ASCII;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;

import javax.crypto.Cipher;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.util.encoders.Hex;

public class ECPublicKeyFactory {

    public static void main(String[] args) throws Exception {

        String name = "secp256r1";

        Security.addProvider(new BouncyCastleProvider());

        // === NOT PART OF THE CODE, JUST GETTING TEST VECTOR ===
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
        ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(name);
        kpg.initialize(ecGenParameterSpec);
        ECPublicKey key = (ECPublicKey) kpg.generateKeyPair().getPublic();
        byte[] x = key.getW().getAffineX().toByteArray();
        byte[] y = key.getW().getAffineY().toByteArray();

        // === here the magic happens ===
        KeyFactory eckf = KeyFactory.getInstance("EC");
        ECPoint point = new ECPoint(new BigInteger(1, x), new BigInteger(1, y));
        ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec(name);
        ECParameterSpec spec = new ECNamedCurveSpec(name, parameterSpec.getCurve(), parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH(), parameterSpec.getSeed());
        ECPublicKey ecPublicKey = (ECPublicKey) eckf.generatePublic(new ECPublicKeySpec(point, spec));
        System.out.println(ecPublicKey.getClass().getName());

        // === test 123 ===
        Cipher ecies = Cipher.getInstance("ECIESwithAES", "BC");
        ecies.init(Cipher.ENCRYPT_MODE, ecPublicKey);
        byte[] ct = ecies.doFinal("owlstead".getBytes(US_ASCII));
        System.out.println(Hex.toHexString(ct));
    }
}

生成Bouncy Castle ECPublicKeyParameters

最初,我认为需要特定于Bouncy Castle的密钥,因此以下代码生成了在Bouncy Castle轻量级API中使用的EC公钥.

Generating Bouncy Castle ECPublicKeyParameters

Initially I thought that a Bouncy Castle specific key was required, so the following code generates the EC public key as used in the Bouncy Castle lightweight API.

package nl.owlstead.stackoverflow;

import java.math.BigInteger;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

public class BC_EC_KeyCreator {

    public static void main(String[] args) throws Exception {

        String name = "secp256r1";

        // === NOT PART OF THE CODE, JUST GETTING TEST VECTOR ===
        Security.addProvider(new BouncyCastleProvider());
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
        kpg.initialize(new ECGenParameterSpec(name));
        ECPublicKey key = (ECPublicKey) kpg.generateKeyPair().getPublic();
        byte[] x = key.getW().getAffineX().toByteArray();
        byte[] y = key.getW().getAffineY().toByteArray();

        // assumes that x and y are (unsigned) big endian encoded
        BigInteger xbi = new BigInteger(1, x);
        BigInteger ybi = new BigInteger(1, y);
        X9ECParameters x9 = ECNamedCurveTable.getByName(name);
        ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(name);
        ECCurve curve = x9.getCurve();
        ECPoint point = curve.createPoint(xbi, ybi);
        ECNamedDomainParameters dParams = new ECNamedDomainParameters(oid,
                x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
        ECPublicKeyParameters pubKey = new ECPublicKeyParameters(point, dParams);
        System.out.println(pubKey);

        // some additional encoding tricks
        byte[] compressed = point.getEncoded(true);
        System.out.println(Hex.toHexString(compressed));
        byte[] uncompressed = point.getEncoded(false);
        System.out.println(Hex.toHexString(uncompressed));
    }
}

这主要是棘手的,因为我不想包含任何JCE特定的代码,并且 X9ECParameters 不是 ECDomainParameters 的子类.因此,我使用了从Bouncy Castle代码库中其他位置复制的 ECNamedDomainParameters 的转换.

This was mostly tricky because I didn't want to include any JCE specific code, and X9ECParameters is not a subclass of ECDomainParameters. So I used a conversion to ECNamedDomainParameters copied from elsewhere in the code base of Bouncy Castle.

这篇关于如何制作充气城堡ECPublicKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆