EC 公钥/私钥的文件格式?

cde*_*ker 5 format bouncycastle file elliptic-curve

如果我想将私钥和公钥存储在一个文件中,最容易使用的格式是什么?特别是如果我打算使用 Java 的 BouncyCastle 库?

Tho*_*nin 3

从理论上来看,公钥可以从私钥重新计算出来(计算成本略低于生成单个 ECDSA 签名的成本,或者做 ECDH 的一半,所以速度很快)。因此,从概念上讲,您只需存储私钥,其标准格式是PKCS#8,Java 和java.security.spec.PKCS8EncodedKeySpec. 此外,PKCS#8 格式包括在同一 blob 中选择性地对公钥和私钥进行编码的规定,因此这看起来确实像您正在寻找的内容。

然而,棘手的事情是说服密码提供者(例如 BouncyCastle)提取公钥和/或重新计算它。显然,如果您PKCS8EncodedKeySpec从 PKCS#8 编码的 EC 私钥(也包含公钥)创建一个,BouncyCastle 将非常友好地在内部保留编码公钥的副本,并在您决定重新编码私钥时将其写回PKCS#8 格式。然而,它并没有做任何其他事情。它将它作为一个不透明的斑点来处理。

因此您必须重新计算公钥。通过 JCE 和 BouncyCastle API 以及未实现的位,我发现了以下内容,它似乎可以工作(JDK 1.6.0_24,BouncyCastle 1.46):

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Provider;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JCEECPrivateKey;
import org.bouncycastle.jce.provider.JCEECPublicKey;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;

// Create the provider and an appropriate key factory.
Provider pp = new BouncyCastleProvider();
KeyFactory kf = KeyFactory.getInstance("EC", pp);

// Decode the private key (read as a byte[] called 'buf').
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(buf);
PrivateKey sk = kf.generatePrivate(ks);

// Recompute public key.
JCEECPrivateKey priv = (JCEECPrivateKey)sk;
ECParameterSpec params = priv.getParameters();
ECPublicKeySpec pubKS = new ECPublicKeySpec(
    params.getG().multiply(priv.getD()), params);
PublicKey pk = kf.generatePublic(pubKS);

// To reencode the private key.
buf = kf.getKeySpec(sk, PKCS8EncodedKeySpec.class).getEncoded();
Run Code Online (Sandbox Code Playgroud)

从概念上讲,我应该使用kf.getkeySpec()withorg.bouncycastle.jce.spec.ECPrivateKeySpec而不是无情地将私钥强制转换为类JCEECPrivateKey,但 clean 方法似乎尚未在 BouncyCastle 中实现。