前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何从PKCS12证书中解析私钥、公钥和证书序列号

如何从PKCS12证书中解析私钥、公钥和证书序列号

作者头像
十毛
发布2021-06-01 20:09:50
3K0
发布2021-06-01 20:09:50
举报

微信支付对接用到的商户API证书是PKCS12格式,常见后缀名是.p12。调用微信支付接口时,都需要用到私钥和证书序列号,为了方便用户,所以一般要求用户直接上传证书(.p12文件),再由后台解析私钥和证书序列号。 而且因为证书本身是一个文件,不方便存储到数据库,所以也转成BASE64格式后再存储。

直接上代码

代码语言:javascript
复制
public class P12Application {
    public static void main(String[] args) throws Exception {
        //从文件中解析
        try (FileInputStream is = new FileInputStream("apiclient.p12")) {
            System.out.println(P12Info.parse(is, "证书密码"));
        }

        //从Base64加密串中解析
        String p12Base64 = "xxxyyyzzz";
        byte[] base64byte = Base64.getDecoder().decode(p12Base64);
        try (ByteArrayInputStream is = new ByteArrayInputStream(base64byte)) {
            System.out.println(P12Info.parse(is, "证书密码"));
        }
    }

    @Data
    @Builder
    private static class P12Info {
        /**
         * 证书序列号.
         */
        private final String serialNo;

        /**
         * 证书秘钥.
         */
        private final PrivateKey privateKey;

        /**
         * 公钥.
         */
        private final PublicKey publicKey;

        public static P12Info parse(InputStream is, String passwd) throws Exception {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(is, passwd.toCharArray());
            String keyAlias = null; 
            //解析证书,必须有别名
            Enumeration<String> aliases = ks.aliases();
            if (aliases.hasMoreElements()) {
                keyAlias = aliases.nextElement();
            }
            //解析私钥
            PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias, passwd.toCharArray());
            Certificate cert = ks.getCertificate(keyAlias);
            BigInteger serialNumber = ((X509CertImpl) cert).getSerialNumber();
            //证书一般都使用16进制表示
            String certSn = serialNumber.toString(16);
           
            //设置证书序列号和私钥
            return P12Info.builder()
                    .serialNo(certSn)
                    .privateKey(privateKey)
                    .publicKey(cert.getPublicKey())
                    .build();
        }
    }
}

常见问题

  • 解析的私钥和公钥都是空:需要检查证书别名是否正确
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 直接上代码
  • 常见问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档