Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write x509 certificate into PEM formatted string in java?

Tags:

java

pem

der

x509

Is there some high level way to write an X509Certificate into a PEM formatted string? Currently I'm doing x509cert.encode() to write it into a DER formatted string, then base 64 encoding it and appending the header and footer to create a PEM string, but it seems bad. Especially since I have to throw in line breaks too.

like image 358
pizzathehut Avatar asked Jul 22 '10 20:07

pizzathehut


People also ask

Is PEM x509 format?

PEM (originally “Privacy Enhanced Mail”) is the most common format for X. 509 certificates, CSRs, and cryptographic keys. A PEM file is a text file containing one or more items in Base64 ASCII encoding, each with plain-text headers and footers (e.g. -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- ).

What is the difference between PEM and x509?

509 is a series of standards, while PEM is just X. 509 object representation in a file (encoding). Literally any data can be represented in PEM format. Anything that can be converted to a byte array (and anything can be, because RAM is a very large byte array) can be represented in PEM format.

What is x509 certificate Java?

public abstract class X509Certificate extends Certificate. Abstract class for X. 509 v1 certificates. This provides a standard way to access all the version 1 attributes of an X.


3 Answers

This is not bad. Java doesn't provide any functions to write PEM files. What you are doing is the correct way. Even KeyTool does the same thing,

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

If you use BouncyCastle, you can use PEMWriter class to write out X509 certificate in PEM.

like image 91
ZZ Coder Avatar answered Nov 05 '22 07:11

ZZ Coder


Haven't seen anyone bring up Java 8's Base64.getMimeEncoder method yet - actually allows you to specify both the line length and line separator like so:

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

I looked to see if there was any difference with this ^ vs the standard encoder, and I couldn't find anything. The javadoc cites RFC 2045 for both BASIC and MIME encoders, with the addition of RFC 4648 for BASIC. AFAIK both of these standards use the same Base64 alphabet (tables look the same), so you should fine to use MIME if you need to specify a line length.

This means that with Java 8, this can be accomplished with:

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;
}
like image 34
josh-cain Avatar answered Nov 05 '22 08:11

josh-cain


Previous answer gives compatibility problems with 3de party software (like PHP), because PEM cert is not correctly chunked.

Imports:

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

Code:

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 = cert.getEncoded();
 String pemCertPre = new String(encoder.encode(derCert));
 String pemCert = cert_begin + pemCertPre + end_cert;
 return pemCert;
}
like image 23
kthomeer Avatar answered Nov 05 '22 07:11

kthomeer