php-rsa算法

问题描述

因对接第三方支付渠道接口,对方仅提供了java版本demo,未提供php版本,故只能根据java版本转成php,

一开始看到对方提供的代码一脸懵逼⊙﹏⊙‖∣

先看java版本核心代码

//签名
public String sign(String content, String privateKey) {
    try {
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
                Base64.decode(privateKey));
        KeyFactory keyf = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyf.generatePrivate(priPKCS8);
        java.security.Signature signature = java.security.Signature
                .getInstance("SHA1WithRSA");
        signature.initSign(priKey);
        signature.update(content.getBytes());
        byte[] signed = signature.sign();
        return Base64.encode(signed);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
//校验
public boolean doCheck(String content, String sign, String publicKey) {
    try {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] encodedKey = Base64.decode(publicKey);
        PublicKey pubKey = keyFactory
                .generatePublic(new X509EncodedKeySpec(encodedKey));
        java.security.Signature signature = java.security.Signature
                .getInstance("SHA1WithRSA");
        signature.initVerify(pubKey);
        signature.update(content.getBytes());
        boolean bverify = signature.verify(Base64.decode(sign));
        return bverify;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

看到RSA、SHA1WithRSA、Base64、PKCS8EncodedKeySpec、X509EncodedKeySpec这些名词后,内心是沮丧的,直接翻译是行不通的,只能祭出Google大杀器来。

经过几个关键词组合尝试后,终于在gist上找到眉目,直达连接 事例代码用的bin2hex、hex2bin,我们直接替换为base64_encode、base64_decode试试看,竟然一次通过,和java版本的加密解密结果是一致的

解决方案

  • openssl下载

  • 生成ssl证书

  • openssl genrsa -out key.pem 1024
    openssl rsa -in key.pem -pubout -outform PEM -out pubkey.pem
    openssl rsa -in key.pem -pubout -outform DER -out pubkey.der
    
  • 代码实现

  • //签名
    function buildSign($content) {
        $signature = null;
        $pri_key = file_get_contents('key.pem');
        $pri_key_id = openssl_get_privatekey($pri_key);
        openssl_sign($content, $signature, $pri_key_id);
        openssl_free_key($pri_key_id);
        return base64_encode($signature);
    }
    //校验
    function verifySign($sign, $toSign) {
        $signed_data = base64_decode($sign);
        $pub_key = file_get_contents('pubkey.pem');
        $pub_key_id = openssl_get_publickey($pub_key);
        $ret = openssl_verify($toSign, $signed_data, $pub_key_id);
        return $ret;
    }
    
  • openssl_sign和openssl_verify默认算法都是SHA1,如果是其他请在第4个参数中传入,请参考如下

define ('OPENSSL_ALGO_SHA1', 1);
define ('OPENSSL_ALGO_MD5', 2);
define ('OPENSSL_ALGO_MD4', 3);
define ('OPENSSL_ALGO_MD2', 4);
define ('OPENSSL_ALGO_DSS1', 5);
define ('OPENSSL_ALGO_SHA224', 6);
define ('OPENSSL_ALGO_SHA256', 7);
define ('OPENSSL_ALGO_SHA384', 8);
define ('OPENSSL_ALGO_SHA512', 9);
define ('OPENSSL_ALGO_RMD160', 10);

你可能感兴趣的:(php-rsa算法)