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