使用Java读取X.509证书

9

我正在尝试使用Java读取从外部方收到的证书。但是,代码抛出以下错误:

java.lang.RuntimeException: java.security.cert.CertificateException:无法初始化,java.io.IOException:向DerValue构造函数提供额外数据

代码如下:

FileInputStream ksfis = new FileInputStream(this.getCertificateFile());
ksbufin = new BufferedInputStream(ksfis);
certificate = (X509Certificate)
  CertificateFactory.getInstance("X.509").generateCertificate(ksbufin);

为了确保问题不在代码中,我创建了自签名证书并将其与代码一起使用,结果工作正常。我已将两个证书安装在系统密钥链中,并且它们都有效。我正在使用Mac和Java 1.6。
当我加载外部Party证书时为什么会出现以上异常,你有任何想法吗?你认为它在传输过程中损坏了吗?如果是这样,它不应该在本地系统上显示为有效,对吗?

谢谢。我是否必须使用Bouncy Castle才能读取它,还是Java中有其他选项?另外,什么是默认格式(自签名证书上的格式)? - Java
DER通常用于编码证书,PEM主要用于电子邮件并是openssl的默认格式。请尝试使用此链接:http://www.bouncycastle.org/docs/pkixdocs1.5on/org/bouncycastle/openssl/PEMReader.html。在默认的JRE库中没有Java PEM解码器。您正在使用一个DER(ASN.1)编码的证书。 - Maarten Bodewes
1
@MaartenBodewes:(因为被顶起来了)记录一下,这些评论是错误的。自至少1.5大约2005年以来,Java的CertificateFactory可以读取PEM或DER格式,尽管在7之前(非常接近此问题),它无法处理带有_额外数据的PEM块,例如某些程序 cough OpenSSL cough 添加的“注释”,并且会抛出一个错误的异常,错误地暗示PEM不受支持。另一方面,KeyFactory只支持DER格式,而KeyStore仅支持二进制格式(PKCS12的DER格式,JKS和JCEKS的Java序列化格式,但不支持PEM)。PEM格式的起始标记应该是BEGIN而不是START,并且连字符和单词之间不应该有空格。... - dave_thompson_085
由于 OP 已经离开并且没有数据,我们无法知道问题是什么,但它“不是” PEM。 - dave_thompson_085
是的,确实如此。令我惊讶的是,CertificateFactory 的输入流支持 PEM 格式。 - Maarten Bodewes
显示剩余3条评论
1个回答

9

试着使用openssl来输入以下内容,然后导入结果:

openssl x509 -outform der -in certificate.pem -out certificate.der

您可以使用轻量级API中的Java Bouncy Castle功能,或者访问以下链接:http://www.bouncycastle.org/docs/pkixdocs1.5on/org/bouncycastle/openssl/PEMReader.html。您可以对结果进行重新编码,然后在Java中使用“X509”证书生成器来获取JCE定义的证书。
ByteArrayInputStream certStream  =  new ByteArrayInputStream(binaryCert);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certStream);

就我个人而言,BouncyCastle 轻量级 API 也给了我一个非常类似的错误。 - cmbaron
并非所有证书都是平等的,@cmbaron,我见过许多编码错误。如果您确定您的代码应该可以工作(请询问Bouncy邮件列表),那么也可能是您的证书问题。 - Maarten Bodewes
1
我和 OP 一样遇到了同样的错误,在我的情况下,原因是行末有额外的空格。 - David Balažic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接