有时别人发来的密钥或证书文件无法读取 , 也可使用openssl确认一下 , 如果openssl能读出来 , 那大概率是自己程序有问题 , 如果openssl读不出来 , 那大概率是别人发的文件有问题 , 如下:
# 查看pkcs1 rsa私钥openssl rsa -in rsa_private_key_pkcs1.key -text -noout# 查看pkcs1 rsa公钥openssl rsa -RSAPublicKey_in -in rsa_public_key_pkcs1.key -text -noout# 查看x.509证书openssl x509 -in cert.crt -text -nocert# 查看pkcs12密钥库文件openssl pkcs12 -in keystore.p12keytool -v -list -storetype pkcs12 -keystore keystore.p12
由于密钥、证书、密钥库文件 , 其实都是使用ASN.1语法描述的 , 所以它们都能按ASN.1语法解析出来 , 如下:
openssl asn1parse -i -inform pem -in cert.crt
证书格式转换某些情况下 , 我们需要在不同格式的密钥或证书文件之间转换 , 也可使用openssl命令来完成 。密钥格式转换 , 如下:
# rsa公钥转换为X509公钥openssl rsa -RSAPublicKey_in -in rsa_public_key_pkcs1.key -pubout -out public_key_x509.key# rsa私钥转换为PKCS8格式openssl pkcs8 -topk8 -inform PEM -in rsa_private_key_pkcs1.key -outform PEM -nocrypt -out private_key_pkcs8.key# pkcs8转rsa私钥openssl pkcs8 -inform PEM -nocrypt -in private_key_pkcs8.key -traditional -out rsa_private_key_pkcs1.key
证书格式转换 , 如下:
# 证书DER转PEMopenssl x509 -inform der -in cert.der -outform pem -out cert.pem -noout# x509证书转pkcs7证书openssl crl2pkcs7 -nocrl -certfile cert.crt -out cert.p7b# 查看pkcs7证书openssl pkcs7 -print_certs -in cert.p7b -noout
由于密钥库中包含证书与私钥 , 故可以从密钥库文件中提取出证书与私钥 , 如下:
# 从pkcs12密钥库中提取证书openssl pkcs12 -in keystore.p12 -clcerts -nokeys -out cert.crt# 从pkcs12密钥库中提取私钥openssl pkcs12 -in keystore.p12 -nocerts -nodes -out private_key.key# pkcs12转jkskeytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -srcalias demo -destkeystore keystore.jks -deststoretype jks -deststorepass 123456 -destalias demo# 从jks中提取证书keytool -export -alias demo -keystore keystore.jks -file cert.crt
读取密钥或证书文件使用JCA来读取密钥或证书文件 , 也是非常方便的 。
PEM转DER若要将PEM格式文件转换为DER , 只需要把---BEGIN XXX---
与---END XXX---
去掉 , 然后使用Base64解码即可 , 如下:
private static byte[] pemFileToDerBytes(String pemFilePath) throws IOException {InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(pemFilePath);String pemStr = StreamUtils.copyToString(is, StandardCharsets.UTF_8);//去掉---BEGIN XXX---与---END XXX---pemStr = pemStr.replaceAll("---+[^-]+---+", "").replaceAll("\\s+", "");//base64解码为DER二进制内容return Base64.getDecoder().decode(pemStr);}
读取PKCS8私钥在JCA中 , 使用PKCS8EncodedKeySpec解析PKCS8私钥文件 , 如下:
public static void testPkcs8PrivateKeyFile() {byte[] derBytes = pemFileToDerBytes("cert/private_key_pkcs8.key");PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(derBytes);RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey)KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);BigInteger n = rsaPrivateCrtKey.getModulus();BigInteger e = rsaPrivateCrtKey.getPublicExponent();BigInteger d = rsaPrivateCrtKey.getPrivateExponent();System.out.printf(" n: %X \n e: %X \n d: %X \n", n, e, d);BigInteger plain = BigInteger.valueOf(new Random().nextInt(1000000000));// RSA加密long t1 = System.nanoTime();BigInteger secret = plain.modPow(e, n);long t2 = System.nanoTime();// RSA解密BigInteger plain2 = secret.modPow(d, n);long t3 = System.nanoTime();System.out.printf(" plain: %d \n plain2: %d \n", plain, plain2);System.out.printf("enc time: %d \n", (t2 - t1));System.out.printf("dec time: %d \n", (t3 - t2));}
经验总结扩展阅读
- [WPF] 抄抄超强的苹果官网滚动文字特效实现
- Java函数式编程:一、函数式接口,lambda表达式和方法引用
- 不妨试试更快更小更灵活Java开发框架Solon
- 11 微服务架构学习与思考:开源 API 网关02-以 Java 为基础的 API 网关详细介绍
- java 新特性之 Stream API
- java 入土--集合详解
- 4 Java I/O:AIO和NIO中的Selector
- 2023容易暴富的星座女实现质的飞跃
- 通过 Github Action 实现定时推送天气预报
- 3 Java I/O:NIO中的Buffer