通过扩展pem从文件获取RSAPublicKey

时间:2015-03-06 13:04:54

标签: java-ee rsa public-key-encryption public-key pem

我正在尝试将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。

如何更正此代码?

1 个答案:

答案 0 :(得分:2)

Java希望您的密钥是DER编码的,但您提供的是PEM编码数据。

将您的文件作为字符串读取,切断标题并对内容进行base64解码。然后将这些字节提供给密钥工厂。