2

I am trying to decode a PEM encoded file using java. There is a very similar question posted already, however it is for DER encoded files, as opposed to PEM encoded files.

openssl -decrypt by Java

The CMSEnvelopedDataParser used there doesn't seem to be suitable for my job. What can I use instead? I am struggling to find a working example online. Any snippet would be very appreciated.

To recreate the problem one can simply follow the steps below.

openssl req -nodes -new -x509 -keyout private.pem -out cert.cert
openssl rsa -pubout -in private.pem -out public.pem 
openssl smime -encrypt -outform PEM -inkey public.pem -in text.txt -out text.txt.pem cert.cert

Then the command I am trying to replace with java is the following:

openssl smime -decrypt -inform PEM -in text.txt.pem -out dec.txt -inkey private.pem
mk4910
  • 23
  • 2

1 Answers1

1

PEM format (now that actual PEM is gone) is mostly (including here) DER encoded in base64 with line breaks and ----BEGIN x----- and -----END x----- lines added; see https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail .

Bouncy provides a group of related classes to handle PEM:

org.bouncycastle.util.io.pem.PemObject obj = new org.bouncycastle.util.io.pem.PemReader(reader).readPemObject();
// where reader is a java.io.Reader that reads the PEM such as a FileReader on a file 
if( !obj.getType().equals("PKCS7") ) throw error; // or maybe CMS -- optional 
... CMSEnvelopedDataParser (obj.getContent()) and on from there

or the Q&D way to do it yourself is something like:

StringBuilder b64 = new StringBuilder();
try( Reader rdr = new BufferedReader (new FileReader (filename)) ){
    for( String line; (line = rdr.readLine()) != null; )
        if( !line.startsWith ("-----") ) b64.append (line);
        // else optionally check for errors?
} // or use a Stream/filter/collect if you prefer 
byte[] der = Base64.getDecoder().decode(pem);
... CMSEnvelopedDataParser (der) and on from there 
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70