java.security.InvalidKeyException: IOException : Short read of DER length
Yesterday, I lost an hour of work trying to debug a less-than-helpful Java error message. When I Googled for the error, the only result that came up was the actual Java source code. As such, I wanted to document this error message in case others come across it. The error message:
java.security.InvalidKeyException: IOException : Short read of DER length
This error wasn't related to the part of the code that I was working on, so it wasn't immediately apparent what was going wrong. The line of code in question was attempting to generate an RSA signature using a private key that was being pulled out of the environmental variables. It was only after logging out the environmental variables that I realized the private key was empty in my local development environment.
Once I saw that my private key was empty, the "short read" kinda sorta maybe makes sense. But, it is definitely a poorly worded error message - one that could easily be improved to be more insightful.
Anyway, here's some sample code that demonstrates the RSA signing error:
<cfscript>
// CAUTION: Notice that I am passing in "" as the private key!!
generateRsaSignature( "SHA256withRSA", "", "There's something about you that sticks." );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I generate an RSA signature for the given message using the given algorithm and key.
*
* CAUTION: Not all algorithms are supported - it depends on how many security
* providers you have installed in your Java runtime environment.
*
* @algorithm I am the signing algorithm (ex, MD5withRSA, SHA256withRSA).
* @key I am the plain-text private key used to sign the message.
* @message I am the plain-text message being signed.
* @output false
*/
public string function generateRsaSignature(
required string algorithm,
required string key,
required string message
) {
var keySpec = createObject( "java", "java.security.spec.PKCS8EncodedKeySpec" )
.init( binaryDecode( key, "base64" ) )
;
var keyFactory = createObject( "java", "java.security.KeyFactory" )
.getInstance( javaCast( "string", "RSA" ) )
;
var privateKey = keyFactory.generatePrivate( keySpec );
var signature = createObject( "java", "java.security.Signature" )
.getInstance( javaCast( "string", algorithm ) )
;
signature.initSign( privateKey );
signature.update( charsetDecode( message, "utf-8" ) );
return( lcase( binaryEncode( signature.sign(), "base64" ) ) );
}
</cfscript>
As you can see, I'm passing-in an empty-string for the private key value, which will generate the InvalidKeyException IO error mentioned above.
If you are interested in generting and verifying RSA signatures in ColdFusion, I played around with a ColdFusion Component (CFC) that encapsulates the ceremony of creating the intermediary Java objects.
Want to use code from this post? Check out the license.
Reader Comments