我正在尝试将Paybox Payment Gateway集成到我的应用程序中。付款后,Paybox会给我一个签名,我必须验证它。
我有Paybox提供的测试密钥,'TestK004.prv.pem'和'TestK004.pub.pem'。
这是我的测试类:
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);
}
}
我公钥的内容是:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLzJXB + BM10Ksdtk0rYHboIKPc o8RXGikLiQQawNXuW4g38uaTbci7xuoH3Cvhngr9OgvKKILKJZiy1FI + NnKT + 8GP 28JHzplbqpc2mmVZ5OT4Xe9D5ndnPVdZ1xUxyBlJshcTYqkSPru9eVNza7jwEqPv DFZBxJoBFScQOJZcpwIDAQAB
----- END PUBLIC KEY -----
当我运行它时,会出错:
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
它无法从密钥文件生成RSAPublicKey。
如何更正此代码?
答案 0 :(得分:2)
Java希望您的密钥是DER编码的,但您提供的是PEM编码数据。
将您的文件作为字符串读取,切断标题并对内容进行base64解码。然后将这些字节提供给密钥工厂。