java读取微信Pem格式证书对字段加密

在微信支付中,有些时候需要对某些字段进行RSA加密,如:
需要加密的字段.png

总体的加密流程如下:
RSA算法使用说明.png

微信通过
获取公钥的接口.png

通过该接口获取到的是PKCS#1类型的公钥,可以直接复制其内容到文本中并将后缀修改为pem格式(如public.pem)
PKCS#1.png

微信提供了pem格式的公钥,但没有详细的使用说明(读取、加密方法),
网上的方法介绍也不是很详细,所开发的JAVA项目中用到的,是另外一种格式(PKCS#8),
PKCS#8.png

可以利用微信页面中的方法将PKCS#1转换为PKCS#8格式的证书,
转换方法.png

其实这两证书的区别就是虚线部分不同,密钥串是相同的。
通过上面的操作,已经获取公钥,下面就是其使用了,
读取公钥:
/**
     * 根据pem公钥路径获取公钥字符串
     *
     * @param cerPath 路径
     * @return 公钥字符串
     */
    public static String getPubKeyContentString(String cerPath) {

        // 读取本机存放的PKCS8证书文件
        String currentPath = Thread.currentThread().getContextClassLoader().getResource(cerPath).getPath();
        try {
            //读取pem证书
            BufferedReader br = new BufferedReader(new FileReader(currentPath));

            StringBuffer publickey = new StringBuffer();
            String line;

            while (null != (line = br.readLine())) {
                if ((line.contains("BEGIN PUBLIC KEY") || line.contains("END PUBLIC KEY")))
                    continue;
                publickey.append(line);
            }
            return publickey.toString();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

将公钥字符串转换为公钥:

/**
     * 根据公钥字符串获取公钥
     * @param key 公钥字符串
     * @return 返回公钥
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new Base64().decode(key));
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

进行加密:

/**
     * 获取加密结果
     * @param data 加密内容
     * @param cerPath 证书路径
     * @return 加密后的字符串
     */
    public static String getDataWithPem(String data,String cerPath) {
        //获取pubkey字符串内容
        String key=getPubKeyContentString(cerPath);

        PublicKey publicKey = null;
        Cipher cipher = null;
        try {
            publicKey = getPublicKey(key);
            cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] test = cipher.doFinal(data.getBytes("utf-8"));
            byte[] bytes = Base64.encodeBase64(test);
            String s = new String(bytes, "utf-8");
            System.out.println("加密结果【" + s);
            return s;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

加密后即可得到344位的加密结果。

相关链接:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7

你可能感兴趣的:(java读取微信Pem格式证书对字段加密)