在java中写入x509证书到PEM格式的string?

是否有一些高水平的方式来写一个X509Certificate成PEM格式的string? 目前我正在做x509cert.encode()将其写入一个DER格式化的string,然后base 64编码它,并添加页眉和页脚创build一个PEMstring,但它似乎不好。 特别是因为我不得不抛出分行。

这并不坏。 Java不提供任何函数来编写PEM文件。 你在做什么是正确的方法。 即使KeyTool也是这样做的,

BASE64Encoder encoder = new BASE64Encoder(); out.println(X509Factory.BEGIN_CERT); encoder.encodeBuffer(cert.getEncoded(), out); out.println(X509Factory.END_CERT); 

如果使用BouncyCastle,则可以使用PEMWriter类在PEM中写出X509证书。

以前的答案给3de party软件(如PHP)的兼容性问题,因为PEM证书没有正确分块。

import:

 import org.apache.commons.codec.binary.Base64; 

码:

 protected static String convertToPem(X509Certificate cert) throws CertificateEncodingException { Base64 encoder = new Base64(64); String cert_begin = "-----BEGIN CERTIFICATE-----\n"; String end_cert = "-----END CERTIFICATE-----"; byte[] derCert = x509cert.getEncoded(); String pemCertPre = new String(encoder.encode(derCert)); String pemCert = cert_begin + pemCertPre + end_cert; return pemCert; } 

以下使用没有大的外部库或版本不一致的sun。*库。 它build立在Judoman的答案之上,但是它也按照OpenSSL,Java和其他语言的要求,分成64个字符的行。

import:

 import javax.xml.bind.DatatypeConverter; import java.security.cert.X509Certificate; import java.io.StringWriter; 

码:

 public static String certToString(X509Certificate cert) { StringWriter sw = new StringWriter(); try { sw.write("-----BEGIN CERTIFICATE-----\n"); sw.write(DatatypeConverter.printBase64Binary(cert.getEncoded()).replaceAll("(.{64})", "$1\n")); sw.write("\n-----END CERTIFICATE-----\n"); } catch (CertificateEncodingException e) { e.printStackTrace(); } return sw.toString(); } 

(我刚刚评论过司法人员的回答,但是我没有足够的声望被允许发表评论,而我的简单编辑被拒绝了,因为它应该是评论或答案,所以这里是答案。)

如果要直接写入文件,还要import java.io.FileWriter和:

 FileWriter fw = new FileWriter(certFilePath); fw.write(certToString(myCert)); fw.close(); 

还没有看到任何人提出Java 8的Base64.getMimeEncoder方法 – 实际上允许你指定行长度行分隔符如下所示:

 final Base64.Encoder encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes()); 

我期待着看看这个和标准编码器有什么不同,我找不到任何东西。 javadoc引用了BASIC和MIME编码器的RFC 2045 ,增加了用于BASIC的RFC 4648 。 AFAIK这两个标准都使用相同的Base64字母表(表看起来相同),所以如果需要指定行长度,则应该使用MIME。

这意味着在Java 8中,这可以通过以下方式来完成:

 import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.util.Base64; 

 public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; public static final String END_CERT = "-----END CERTIFICATE-----"; public final static String LINE_SEPARATOR = System.getProperty("line.separator"); 

 public static String formatCrtFileContents(final Certificate certificate) throws CertificateEncodingException { final Base64.Encoder encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes()); final byte[] rawCrtText = certificate.getEncoded(); final String encodedCertText = new String(encoder.encode(rawCrtText)); final String prettified_cert = BEGIN_CERT + LINE_SEPARATOR + encodedCertText + LINE_SEPARATOR + END_CERT; return prettified_cert; } 

要build立在ZZ编码器的思想上,但不使用不保证在JRE版本之间保持一致的sun.misc类,请考虑

使用类:

 import javax.xml.bind.DatatypeConverter; 

码:

 try { System.out.println("-----BEGIN CERTIFICATE-----"); System.out.println(DatatypeConverter.printBase64Binary(x509cert.getEncoded())); System.out.println("-----END CERTIFICATE-----"); } catch (CertificateEncodingException e) { e.printStackTrace(); } 

如果你有来自充气城堡的PEMWriter,那么你可以做到以下几点:

import:

 import org.bouncycastle.openssl.PEMWriter; 

代码:

 /** * Converts a {@link X509Certificate} instance into a Base-64 encoded string (PEM format). * * @param x509Cert A X509 Certificate instance * @return PEM formatted String * @throws CertificateEncodingException */ public String convertToBase64PEMString(Certificate x509Cert) throws IOException { StringWriter sw = new StringWriter(); try (PEMWriter pw = new PEMWriter(sw)) { pw.writeObject(x509Cert); } return sw.toString(); }