在Java中存储KeyStore:空文件,无法重新加载

时间:2014-02-04 13:25:58

标签: java serialization certificate x509certificate keystore

所以,我的问题有一些非常具体的部分,但我会尽力将这些部分留下来。

我正在尝试做什么:我正在插入我的eID卡(电子身份证)。理论上,我应该能够使用Java KeyStore保存其上的密钥库和证书。我可以这样加载eID卡:

/*Load from eID*/
KeyStore keyStore = null;
try (FileOutputStream fos = new FileOutputStream(Constants.fullFileEID)) {
    /*Load*/
    Security.addProvider(new BeIDProvider());
    keyStore = KeyStore.getInstance("BeID");
    keyStore.load(null);

所以我正在加载keyStore(通过添加提供程序,这可能归功于我添加的外部库)。对于记录:常量是我正在使用的常量类,而fullFileEID是应该保存EID的完整文件路径(路径,文件本身除外)。

然后我尝试打开一些细节(我正在登录一个文件,因为我已经在我的System.out中获得了一个非常大的日志,只是为了保持清晰):

    /*Test*/
    FileLogging.writeToFile("Type: " + keyStore.getType());
    FileLogging.writeToFile("Authentication certificate: " + keyStore.getCertificate("Authentication").getClass());
    FileLogging.writeToFile("Authentication serialized: " + Serialization.serialize(keyStore.getCertificate("Authentication")));
    FileLogging.writeToFile("Signature certificate: " + keyStore.getCertificate("Signature").getClass());
    FileLogging.writeToFile("Signature serialized: " + Serialization.serialize(keyStore.getCertificate("Signature")));
    FileLogging.writeToFile("Provider: " + keyStore.getProvider());
    FileLogging.writeToFile("Should be saved in " + Constants.fullFileEID);

我在那里收到很多有趣的细节。它不是空的,一切看起来都很完美(我的keyStore中有两个别名,“Authentication”和“Signature”)。对于记录:序列化是我的另一个Helper类,它将对它接收的对象进行序列化和Base64编码 - serialize函数接收Serializable作为参数。

这就是我得到的(我截断了序列化的字符串):

Type: BeID
Authentication certificate: class sun.security.x509.X509CertImpl
Authentication serialized: rO0ABXNyAC1qYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlma[...]
Signature certificate: class sun.security.x509.X509CertImpl
Signature serialized: rO0ABXNyAC1qYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdG[...]
Provider: BeIDProvider version 1.0
Should be saved in [fullFilePath]\eID.jks

因此证书本身来自“普通”类,它们不是子类,所以我不知道应该出现在序列化方法中的任何特殊内容......因此,序列化本身也可以完美地运行。 / p>

好的,所以测试是积极的,我认为:实际存储我的文件的时间。

    /*Save*/
    keyStore.store(fos, "xxxx".toCharArray());
    System.out.println("keystore: ");
    keyStore.store(System.out, "xxxx".toCharArray());
} catch (Exception e) {
    Util.handleLogging(e);
}

所以,我使用我在上面创建的FileOutputStream来{key}的密钥库。 (“xxxx”是密码 - 我不确定它是否需要是卡的密码,因为我已经可以阅读并打印证书卡的内容,而不会给出任何密码)。我还尝试将输出“打印”到System.out。

现在是有趣的部分:创建的文件是空的。它由此函数创建(或者至少会覆盖先前的文件)。如果文件不存在则会创建。但它是0kb大,当然,它不起作用。

我做错了什么?我真的没有看到什么是错的?我怀疑在实际保存期间是否出现任何问题,我至少会得到一个例外(比如CertificateException,如果密钥库数据中包含的任何证书无法沿着文档存储,那么应该抛出它)?

我不得不承认,我不喜欢这样的事实,没有人需要为我提供密码以便能够从卡中读取数据。这对我来说不合适。

1 个答案:

答案 0 :(得分:1)

比利时eID具有Java Keystore的特定实现。如果您查看实现be.fedict.commons.eid.jca.BeIDKeyStore,那么您将看到商店方法未实现。

@Override
public void engineStore(final OutputStream stream, final char[] password)
        throws IOException, NoSuchAlgorithmException, CertificateException {
}

我遇到了同样的问题,但我还没有找到解决方案。