将P-256 DH java字符串转换为java PublicKey

时间:2017-04-05 16:15:37

标签: java diffie-hellman

我正在尝试向我的浏览器发送网络推送通知,并且能够成功订阅。我得到一个订阅对象“P-256曲线上的椭圆曲线Diffie-Hellman公钥”。

我想在Java中将此字符串转换为公钥,但仍会出现无效的密钥格式异常。

这是我正在尝试的代码:

  String publicK = "BBoN_OkTfE_0uObues82qHr96z8x3nepYoUwCBoftFDS_Vgx2MUHN1vAFxc1eDiyDrvmZ2bQ4sJq3F8Qz71RWI0=";
  byte[] publicBytes = publicK.getBytes();
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
  KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
  PublicKey pubKey = keyFactory.generatePublic(keySpec);

有人可以帮帮我吗?加密noob在这里:/

1 个答案:

答案 0 :(得分:1)

对于我的代码,我使用了 java 1.7 BouncyCastle 库。如果您使用maven,只需添加到 pom.xml

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk16</artifactId>
    <version>1.46</version>
</dependency>

或者在BouncyCastle网站下载这些广告。这是一个用于java的加密API,包含许多有用的东西(包括处理椭圆曲线键的类)。

用于读取公钥和转换为对象的代码是:

import java.security.KeyFactory;
import java.security.Security;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;

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


// you need to add the BouncyCastle provider to use its functionalities
Security.addProvider(new BouncyCastleProvider());

String publicK = "BBoN_OkTfE_0uObues82qHr96z8x3nepYoUwCBoftFDS_Vgx2MUHN1vAFxc1eDiyDrvmZ2bQ4sJq3F8Qz71RWI0=";
// publicK is encoded in base64, so you need to decode it first
byte[] publicBytes = Base64.decode(publicK.getBytes());

// spec for P-256 curve
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
// create a KeyFactory with ECDSA (Elliptic Curve Diffie-Hellman) algorithm and use BouncyCastle as the provider
KeyFactory kf = KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);

// code below just creates the public key from the bytes contained in publicK
// using the curve parameters (spec variable)
ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
ECPoint point = ECPointUtil.decodePoint(params.getCurve(), publicBytes);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);

System.out.println(pk.toString());

输出:

EC Public Key
            X: 1a0d00e9137c4034b8e6ee7acf36a87afdeb3f31de77a9628530081a1fb450d2
            Y: 15831d8c507375bc01717357838b20ebbe66766d0e2c26adc5f10cfbd51588d

备注

  • 我不知道椭圆曲线键背后的所有数学,只是基本的想法。我知道曲线的参数类似Gn(通过getG()getN()方法获得)并且有一些“标准的预定义”曲线(像P-256那样你可以使用ECNamedCurveTable.getParameterSpec()

  • 如果需要,您可以查看所有math details。还有一个list of different standard curves,哪些被认为是安全的。

  • ECPublicKey扩展了PublicKey,因此您可以像PublicKey

  • 一样使用它