java - Java中存储KeyStore : empty file and unable to reload

标签 java serialization certificate x509certificate keystore

所以,我的问题有一些非常具体的部分,但我会尽力尽可能地省略这些部分。

我正在尝试执行的操作:我正在插入我的 eID 卡(电子身份证)。理论上,我应该能够使用 Java KeyStore 保存 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(通过添加提供程序,这可能要归功于我添加的外部库)。郑重声明:Constants 是我正在使用的常量类,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 中有两个别名,“身份验证”和“签名”)。郑重声明:Serialization 是我的另一个 Helper 类,它将序列化并对其接收的对象进行 Base64 编码 - serialize 函数接收 Serialized 作为参数。

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

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

因此,证书本身来自“正常”类,它们没有子类化,因此序列化方法中不应该存在我不知道的特殊内容......因此,序列化本身也可以完美运行。

好的,所以测试是积极的,我想:是时候实际存储我的文件了。

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

因此,我使用上面创建的 FileOutputStream store key 存储到. (“xxxx”是密码 - 我不确定它是否需要是卡的密码,因为我已经可以读取和打印经过认证的卡的内容,而无需提供任何密码)。我还尝试将输出“打印”到 System.out。

现在是有趣的部分:创建的文件是空的。它是由该函数创建的(或者至少覆盖较早的文件)。如果该文件不存在,则创建该文件。但它有0kb大,当然不行。

我做错了什么?我真的不明白有什么问题?我怀疑如果在实际保存过程中出现任何问题,我至少会得到一个异常(例如CertificateException,应该抛出“如果 keystore 数据中包含的任何证书无法存储”文档)?

我必须承认这样一个事实,我不喜欢没有人需要提供密码才能让我读取卡上的数据。我感觉不太对劲。

最佳答案

比利时 eID 有 Java keystore 的特定实现。如果您查看一下 be.fedict.commons.eid.jca.BeIDKeyStore 的实现,您会发现 store 方法未实现。

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

我也遇到了同样的问题,目前还没找到解决办法。

关于java - Java中存储KeyStore : empty file and unable to reload,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21553797/

相关文章:

c# - 通过属性在(反)序列化期间控制枚举值格式

python - 尝试抓取网页时出现 SSL 错误

ios - iOS App 中的自定义证书

java - 我应该使用什么布局来显示聊天记录

java - 一种基于云分区的公有云负载均衡模型

java - 当 Java 进程退出时,JNI DLL 使用的内存是否会返回?

serialization - 使用 ServiceStack Redis/TextSerializer 序列化父类字段

java - 在 Java 中使用流进行序列化

azure - 如何使用 Powershell 获取与服务主体关联的证书的指纹?

java - Linkedhashmap里面的ArrayList of Objects,获取数据