美文网首页
使用Java从PKCS12证书中解析私钥、公钥和证书编号

使用Java从PKCS12证书中解析私钥、公钥和证书编号

作者: 十毛tenmao | 来源:发表于2021-05-29 10:56 被阅读0次

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

    直接上代码

    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();
            }
        }
    }
    

    常见问题

    • 解析的私钥和公钥都是空:需要检查证书别名是否正确

    相关文章

      网友评论

          本文标题:使用Java从PKCS12证书中解析私钥、公钥和证书编号

          本文链接:https://www.haomeiwen.com/subject/pezesltx.html