Bouncycastle DER length IO error:

Martin Clemens Bloch picture Martin Clemens Bloch · Dec 11, 2014 · Viewed 14.4k times · Source

This is my method:

import org.bouncycastle.asn1.ASN1InputStream;
import java.io.ByteArrayInputStream;
...
public static byte[] toDERBytes(byte[] data) throws IOException
{
    ByteArrayInputStream inStream = new ByteArrayInputStream(data);

    //Uses imported bouncy castle library:
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream);
    byte[] derArray = asnInputStream.readObject().getEncoded();
    asnInputStream.close();

    return derArray;
}

According to the BouncyCastle documentation I have seen ASN1InputStream.readobject() should actually get a DER object and not ASN1. (To my understanding DER is a subtype of ASN1)

I then return the bytes.

This works half the time, but the other half I get this error:

java.io.IOException: DER length more than 4 bytes: XXX

My questions are:

  1. Why do I only get the error SOMETIMES? (I always give it 65 bytes of data)
  2. How do I fix it?
  3. Am I DER encoding the right way?

Answer

Martin Clemens Bloch picture Martin Clemens Bloch · Dec 12, 2014

The method I call expects encoded data, not the data to be encoded. I'm an idiot.

Idiocy nr. 2: I thought DER was a kind of compression algorithm, but its for encoding objects with well defined types, fields and data. Similar to JSON or XML I guess.

As it turns out the framework I'm going to use this for/in also just uses DER by mistake because it was provided by OpenSSL - it adds no value to that framework as all bytes are already well defined.

It makes no sense to say something like DER(random_byte_string_data) because the result would be something like this, [type;length;data] or in actual bytes: 04 10 <10 bytes of data> (04 is the type used for octet_string = byte arrays)

Personally now that I understand it I don't get the value of DER at all - its not human readable and if you're dealing with bytes at the computers level anyway then why the extra padding? You can only really MAP the DER data if you know what it IS (which DER doesn't tell you unlike XML/JSON) - which means to USE DER you MUST have a pre-established scheme/protocol.

Which leads me back to: If you're dealing with bytes in a predefined environment/protocol, why this gradeschool kind of silly padding and waste of bandwidth/space?

Why not a format that adds checksums and compresses data instead of DER...