【问题标题】:Parse binary data from CSV file - CertificateException从 CSV 文件解析二进制数据 - CertificateException
【发布时间】:2014-08-23 21:53:26
【问题描述】:

我尝试从一个大的 .csv 文件中解析证书数据。文档说它是一个 X509 证书,存储在使用 base64 编码的原始数据中。

所以我尝试使用此代码对其进行解码并使用 java 加载数据:

protected X509Certificate parseCert(byte [] bytes) {
    if (bytes != null) {
        InputStream in = new ByteArrayInputStream(org.apache.commons.net.util.Base64.decodeBase64(bytes));
        X509Certificate certificate = null;
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            certificate = (X509Certificate) cf.generateCertificate(in);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return certificate;
    }

    System.out.println("Null value in bytes!");
    return null;
}

我总是收到CertificateException 说“空数据”。我不知道我做错了什么!

使用 CSV 阅读器,数据看起来不错,或者我必须切断 \x3 吗?

 \x308202e23082024ba0......
 \x30820224308201....

还有:

\ x308201db30820144a00302010202020462300d06092a864886f70d010104050030323130302e0603550403132750616e646f436c69656e74363930413639343632353536363738423737414435353341314332393020170d3133303330383137313230315a180f33303132303232393137313230315a30323130302e0603550403132750616e646f436c69656e743639304136393436323535363637384237374144353533413143323930819f300d06092a864886f70d010101050003818d0030818902818100ad97e2fd61997ca4898383b957de7d44fcf9cf4199c915538fadfd644d36df3ea1eea1d69a6b8ad75a313cb25b479966ed7f831638bbea4ac0f2f2d1452b81ed0ff73da55f477e81f4cd4dad7ca26f29a7eb38d097ec90446e531bac72e29882f1df06a75893f7d6e115d11200bff5a813ea050591f2fcc50ab2d13ddc7d3fdd0203010001300d06092a864886f70d010104050003818100603e9d0ad64f80363e3cae94b28dcb9a25409a59ce7876bd24990b62ef3901788e2c0b3a0be22f4c07deb7c005d82f46a105a6abbfca4505403a7c2248be296aae5367e04fc22b0a93f6272263a3ebf25279e5c1ae415fd9e14898c11dc74c18c128e35e7d8467028689cc304fc95359c1f7eb89018ca750145ea81f498880af P>

有人可以帮忙吗?

【问题讨论】:

  • 我必须切断 \x3 - 尝试切断 \x。其余部分看起来是十六进制编码的,但不是 base64 编码的。
  • 感谢您的快速回复。尝试它导致解析异常:“不完整数据”
  • “不完整的数据” - 也许它不完整。您可能希望为示例失败添加确切的 bytes 字节数组内容。如前所述,数据看起来是十六进制编码的,而不是 base64。你试过十六进制解码吗?
  • 添加了样本数据集
  • 十六进制也以 java.security.cert.CertificateException 结尾:无法解析证书:java.io.IOException:在调试字符串中测试的空输入不为空

标签: csv certificate x509 der


【解决方案1】:

证书不是base64编码的,而是十六进制编码的。

将 OP 的 parseCert 方法的代码更改为

protected X509Certificate parseCert(byte[] bytes)
{
    if (bytes != null)
    {
        InputStream in = new ByteArrayInputStream(Hex.decode(bytes));
        X509Certificate certificate = null;
        try
        {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            certificate = (X509Certificate) cf.generateCertificate(in);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return certificate;
    }

    System.out.println("Null value in bytes!");
    return null;
}

(使用 BouncyCastle 十六进制解码器 org.bouncycastle.util.encoders.Hex,但任何其他也应该这样做)导致证书解析成功

@Test
public void test24542431() throws CertificateEncodingException, IOException
{
    String hexEncodedCert = "308201db30820144a00302010202020462300d06092a864886f70d010104050030323130302e0603550403132750616e646f436c69656e74363930413639343632353536363738423737414435353341314332393020170d3133303330383137313230315a180f33303132303232393137313230315a30323130302e0603550403132750616e646f436c69656e743639304136393436323535363637384237374144353533413143323930819f300d06092a864886f70d010101050003818d0030818902818100ad97e2fd61997ca4898383b957de7d44fcf9cf4199c915538fadfd644d36df3ea1eea1d69a6b8ad75a313cb25b479966ed7f831638bbea4ac0f2f2d1452b81ed0ff73da55f477e81f4cd4dad7ca26f29a7eb38d097ec90446e531bac72e29882f1df06a75893f7d6e115d11200bff5a813ea050591f2fcc50ab2d13ddc7d3fdd0203010001300d06092a864886f70d010104050003818100603e9d0ad64f80363e3cae94b28dcb9a25409a59ce7876bd24990b62ef3901788e2c0b3a0be22f4c07deb7c005d82f46a105a6abbfca4505403a7c2248be296aae5367e04fc22b0a93f6272263a3ebf25279e5c1ae415fd9e14898c11dc74c18c128e35e7d8467028689cc304fc95359c1f7eb89018ca750145ea81f498880af";
    X509Certificate cert = parseCert(hexEncodedCert.getBytes());
    Files.write(FileSystems.getDefault().getPath("target/test-outputs", "24542431.crt"), cert.getEncoded());
}

但这里不可信:

【讨论】:

  • 谢谢,我没有摆脱 \ char ;) 感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 2015-12-31
  • 2020-05-21
  • 2011-11-23
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
相关资源
最近更新 更多