I am trying to implement Paybox Payment Gateway integration to my application. After payment Paybox returns me a signature and I have to verify it.
I have test keys provided by Paybox, 'TestK004.prv.pem' and 'TestK004.pub.pem'.
Here is my Test Class:
package com.alpha.shop.component.payment.methods.crc.impl.ww.paybox;
import java.security.interfaces.RSAPublicKey;
import java.security.Signature;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.io.FileInputStream;
import java.io.DataInputStream;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.net.URLCodec;
public class SignVer {
// verification signature RSA des donnees avec cle publique
private static boolean verify( byte[] dataBytes, byte[] sigBytes, String sigAlg, RSAPublicKey pubKey) throws Exception
{
Signature sig = Signature.getInstance(sigAlg);
sig.initVerify(pubKey);
sig.update(dataBytes);
return sig.verify(sigBytes);
}
// chargement de la cle AU FORMAT der :
// openssl rsa -inform PEM -in pbx_pubkey.pem -outform DER -pubin -out /tmp/pubkey.der
private static RSAPublicKey getPubKey(String pubKeyFile) throws Exception
{
FileInputStream input = new FileInputStream(pubKeyFile);
byte[] fileData = new byte[input.available()];
input.read(fileData);
input.close();
String text = new String(fileData, "UTF-8");
byte[] decoded = Base64.decodeBase64(text);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// extraction cle
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(decoded);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec);
return pubKey;
}
// exemple de verification de la signature
public static void main(String[] unused) throws Exception {
String sData = "Auto=459782&Idtr=201348570&Ref=Ma_commande"; // donnees signees
String sSig = "df123dsfd3...1f1ffsre+t321rt1t3e="; // signature Base64 et URL encodee
// decodage
byte[] sigBytes = Base64.decodeBase64( URLCodec.decodeUrl(sSig.getBytes()));
// lecture de la cle publique
RSAPublicKey pubK = getPubKey("C:/Users/Garip/Desktop/Yeni klasör/TestK004.pub.pem");
// verification signature
boolean result = verify(sData.getBytes(), sigBytes, "SHA1withRSA", pubK);
// affichage resultat
System.out.println("Resultat de la verification de signature : " + result);
}
}
Content of my Public Key is:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLzJXB+BM10Ksdtk0rYHboIKPc o8RXGikLiQQawNXuW4g38uaTbci7xuoH3Cvhngr9OgvKKILKJZiy1FI+NnKT+8gP 28JHzplbqpc2mmVZ5OT4Xe9D5ndnPVdZ1xUxyBlJshcTYqkSPru9eVNza7jwEqPv DFZBxJoBFScQOJZcpwIDAQAB
-----END PUBLIC KEY-----
When I run it, gives error:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at com.alpha.shop.component.payment.methods.crc.impl.ww.paybox.SignVer.getPubKey(SignVer.java:39)
at com.alpha.shop.component.payment.methods.crc.impl.ww.paybox.SignVer.main(SignVer.java:54)Caused by: java.security.InvalidKeyException: invalid key format
at sun.security.x509.X509Key.decode(X509Key.java:387)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:84)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 3 more
It can't generate RSAPublicKey from key file.
How can I correct this code ?
Java expects your key to be DER-encoded, but you are supplying PEM-encoded data.
Read your file as a string, cut off the headers and base64-decode the contents. Then supply those bytes to the key factory.