收藏
回答

微信提供接口获取到的rsa公钥文件pem转成PublicKey的时候报IO异常?

公钥获取接口:

https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_7&index=4

我的做法是用postman固定随机值(和文档示例给的随机值一样32位)后请求这个接口,获得了公钥,然后存到txt,后缀改为pem。公钥如下:

然后用工具类获取了InputStream(公钥pem文件)的字符串,并且打印正常,测试环境正常,生成环境也正常。


接下来要将公钥转为PublicKey类型,有两种方法,两种方法都报了不一样的异常。

1传入参数为公钥字符串(已打印确定就是接口获取到的公钥)

public static PublicKey getPublicKey(String key) throws Exception {
    byte[] keyBytes;
    keyBytes = (new BASE64Decoder()).decodeBuffer(key);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey publicKey = keyFactory.generatePublic(keySpec);-----------------------------本行是报异常的具体位置
    return publicKey;
}


异常:

java.security.InvalidKeyException: IOException : Short read of DER length


2传入参数为InputStream

public static PublicKey getPublicKey(InputStream inputStream, String keyAlgorithm) throws Exception {
    try
    {
        System.out.println("b1.........");
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        System.out.println("b2.........");
        StringBuilder sb = new StringBuilder();
        String readLine = null;
        System.out.println("b3.........");
        while ((readLine = br.readLine()) != null) {
            if (readLine.charAt(0) == '-') {
                continue;
            } else {
                sb.append(readLine);
                sb.append('\r');
            }
        }
        System.out.println("b4.........");
        X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(decodeBase64(sb.toString()));
        System.out.println("b5.........");
        KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
        System.out.println("b6.........");
        //下行出错  java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=127, too big.
        PublicKey publicKey = keyFactory.generatePublic(pubX509);-----------------------------本行是报异常的具体位置

        System.out.println("b7.........");
        return publicKey;
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("b8.........");
        throw new Exception("1这里报异常了:"+e.getMessage(), e);
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            inputStream = null;
            throw new Exception("INPUT STREAM CLOSE ERROR:", e);
        }
    }


异常:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence


我正在做的是企业转账到银行卡功能,请问我这个步骤正确吗?如果正确,那这异常什么原因,要如何解决?

回答关注问题邀请回答
收藏

1 个回答

  • 北望沣渭
    北望沣渭
    2021-08-13

    public key 格式不对,你这个是pkcs#1格式的,末尾的`-----END`需要是单独一行。

    2021-08-13
    有用
    回复 1
    • 丹麦诗人
      丹麦诗人
      2021-08-13
      这是从获取公钥接口直接拿到的,而且我在线转pkcs#8转不了,说:请检查私钥与密码是否匹配。。。微信后台生成密钥对用了什么密码吗?我试了商户号,不行。
      2021-08-13
      回复
登录 后发表内容