I have an external service which call me back after some defined event, and sign his request with its private key.
I have stored the public key which look like :
-----BEGIN PUBLIC KEY-----
........................................
-----END PUBLIC KEY-----
So my work is to check if request’s content has not been alterned by verifying signature.
Here is my algorithm :
// 1 - reading public key :
Scanner scanner = new Scanner( new File( keyPath ) );
// encodedPublicKey.toString( );
StringBuilder sb = new StringBuilder( );
while ( scanner.hasNextLine( ) )
{
sb.append( scanner.nextLine( ) );
sb.append( '\n' );
}
byte[] encodedPublicKey = sb.toString( ).getBytes( "utf-8" );
// 2 - loading public key in a relevant object :
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( publicKeyBytes );
KeyFactory keyFactory = KeyFactory.getInstance( "DSA" );
PublicKey publicKey = keyFactory.generatePublic( publicKeySpec );
// 3 - verifying content with signature and content :
Signature sig = Signature.getInstance( "SHA1withDSA" );
sig.initVerify( publicKey );
sig.update( message.getBytes( ) );
ret = sig.verify( sign.getBytes( ) );
But for now my algorithm is stoped at “PublicKey publicKey = keyFactory.generatePublic( publicKeySpec )” step by this message :
java.security.spec.InvalidKeySpecException: Inappropriate key specification: invalid key format
So how can I load my key in a way that is accepted by java api ?
Actually I’ve found the solution.
The problem was to load in the public key file in the right way.
I’va added bouncycastle library to my dependencies :
It provides PemReader which allows to read and load non certificated public keys.
Here is my utility class :
You just have to pass signed content, signature and key path to checkSign method and it does all the work.