我正在尝试向我的浏览器发送网络推送通知,并且能够成功订阅。我得到一个订阅对象“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在这里:/
答案 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
备注强>:
我不知道椭圆曲线键背后的所有数学,只是基本的想法。我知道曲线的参数类似G
和n
(通过getG()
和getN()
方法获得)并且有一些“标准的预定义”曲线(像P-256那样你可以使用ECNamedCurveTable.getParameterSpec()
。
如果需要,您可以查看所有math details。还有一个list of different standard curves,哪些被认为是安全的。
ECPublicKey
扩展了PublicKey
,因此您可以像PublicKey