使用BouncyCastle从文件中读取椭圆曲线私钥

DCK*_*ing 3 java openssl bouncycastle

BouncyCastle加密API允许使用常规java.security包对象(例如java.security.PublicKey,java.security.PrivateKey及其容器)创建和验证数字签名java.security.KeyPair.

假设我使用OpenSSL创建一个.pem(或者,如果更简单,一个.der文件),其中包含我想在我的应用程序中使用的椭圆曲线私钥.例如,它看起来像这样:

-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
-----END EC PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)

如何使用BouncyCastle API获取java.security.KeyPair包含此私钥和相应公钥的?

请注意我想使用BouncyCastle 1.50中提供的API(在撰写本文时是最新的)并且没有弃用的API.不幸的是,这不包括PEMReader其他SO答案中使用的类.此外,这个问题特定于椭圆曲线的格式; 在比较RSA或DSA密钥文件时,它们包含其他参数.

dav*_*085 10

除了divanov显示的标准JCE方法,只要你给它正确的输入(参见我的评论),或者只是像你的selfanswer一样使用JCE,BouncyCastle 1.48 up DOES仍然包含刚刚组织的旧PEMReader功能有点不同,在这种情况下你可以使用类似的东西:

static void SO22963581BCPEMPrivateEC () throws Exception {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    Reader rdr = new StringReader ("-----BEGIN EC PRIVATE KEY-----\n"
            +"MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK\n"
            +"oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun\n"
            +"GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==\n"+"-----END EC PRIVATE KEY-----\n");
    Object parsed = new org.bouncycastle.openssl.PEMParser(rdr).readObject();
    KeyPair pair = new org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter().getKeyPair((org.bouncycastle.openssl.PEMKeyPair)parsed);
    System.out.println (pair.getPrivate().getAlgorithm());
}
Run Code Online (Sandbox Code Playgroud)


div*_*nov 6

在Java中,这将是几乎相同的代码.剥离保护字符串并解码Base64数据后,将其提供给此实用程序方法:

public static PrivateKey keyToValue(byte[] pkcs8key)
    throw GeneralSecurityException {

    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8key);
    KeyFactory factory = KeyFactory.getInstance("ECDSA");
    PrivateKey privateKey = factory.generatePrivate(spec);
    return privateKey;
}
Run Code Online (Sandbox Code Playgroud)

  • 这对于此Q中的数据(相关部分)不起作用,该数据采用OpenSSL的"遗留"格式,而不是JCE使用的****PKCS8格式**; 注意PEM标题`BEGIN/END EC PRIVATE KEY`_not_`BEGIN/END PRIVATE KEY`用于未加密的PKCS8.您可以在现代版本(1.0.0 up)中使用`openssl pkey -in oldfile -out newfile`或在所有版本中使用`openssl pkcs8 -topk8 -nocrypt -in oldfile -out newfile`转换它,然后将un-base64 _that_转换为` PKCS8EncodedKeySpec`. (6认同)
  • 查看[JCA文档](http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyFactory)让我相信`KeyFactory.getInstance()`的参数是应该是'EC`而不是'ECDSA`.我错了吗? (2认同)
  • 这取决于使用的提供程序。对于 BouncyCastle,它可以是 EC 和 ECDSA。对于 Sun Provider,它可能只是 EC,我用得不多。 (2认同)