Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2095
  • Last Modified:

base64 decoding and verifying signature against a public key

Hello,

I have a message that has a signatured generated for it and I need to validate them against the public key file (/temp/publickey.p7b).  The message and signature were both first url encoded and then the signature was also BASE64-encoded.  I'm using the below to url decode first, then base64 decode the signature and then verify the signature against the public key.  I get an exception on  PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
The signature algorithm used will be SHA-1 with RSA. SHA-1 is the message digest algorithm and RSA is the encryption algorithm.

Exception:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
      at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
      at java.security.KeyFactory.generatePublic(KeyFactory.java:304)

Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
      at sun.security.x509.X509Key.decode(X509Key.java:380)
      at sun.security.x509.X509Key.decode(X509Key.java:386)
      at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
      at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
      at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)



public void decode(){
        String message="message string";
        String signature="signtaure encoded string";


        try{
            String messageDecoded=URLDecoder.decode(message, "UTF-8");
            String signatureUrlDecoded=URLDecoder.decode(signature, "UTF-8");
             
            byte[] decodedSignature = Base64.decodeBase64(signatureUrlDecoded.getBytes());
            String decodedSignatureString = new String(decodedSignature);
            
            FileInputStream publicKeyFile = new FileInputStream("/temp/publickey.p7b");
             
			byte[] encKey = new byte[publicKeyFile.available()];
			publicKeyFile.read(encKey);
			publicKeyFile.close();
			
			X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
			
			Signature sig = Signature.getInstance("SHA1withRSA");
			sig.initVerify(pubKey);
			sig.update(messageDecoded.getBytes());
			boolean verifies = sig.verify(decodedSignature);
         }
         catch(Exception e){
             e.printStackTrace();
         }

	}

Open in new window

0
cgray1223
Asked:
cgray1223
1 Solution
 
btanExec ConsultantCommented:
you may want to check out this API that parses a PKCS#7-formatted (or p7b) certificate reply stored in a file. From the generateCertificates, you will get Certificate instance which is DER-encoded instances of X.509 certificate. you will probably have to enumerate each cert in p7b (as typically it may have a collection) and populate into "encKey" instead

See more in
http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#ParseCert
http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#KeyFactoryEx
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now