无法从x509证书中提取公钥 [英] unable to extract public key from x509 cert
问题描述
这是我的代码:
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.X509EncodedKeySpec;
import java.security.KeyFactory;
class LoadKey {
public static void main(String[] args)
throws InvalidKeySpecException, UnsupportedEncodingException, NoSuchAlgorithmException
{
String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM\n" +
"MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n" +
"THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x\n" +
"MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n" +
"MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n" +
"FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n" +
"gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy\n" +
"wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B\n" +
"d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM\n" +
"BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n" +
"LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n" +
"BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n" +
"Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n" +
"ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n" +
"AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp\n" +
"ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le\n" +
"IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==\n" +
"-----END CERTIFICATE-----\n";
System.out.println(cert);
byte[] encodedCert = cert.getBytes();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedCert);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
}
}
OpenSSL能够通过命令行解码X509证书,因此我知道它是有效的证书.但是Java似乎并不喜欢它.
OpenSSL is able to decode the X509 cert via the command line so I know it's a valid cert. But Java doesn't seem to like it, all the same.
无论有没有尾随的\ n我都累了.
I've tired it with and without the trailing \n to no avail.
有什么想法吗?
推荐答案
--- 更新
如注释中的 dave_thompson_085
所述,OP解决方案的唯一问题是OP使用的是 KeyFactory
用于密钥,而不是 CertificateFactory
用于证书.
As mentioned by dave_thompson_085
in the comments, only thing wrong with OP's solution is that OP is using KeyFactory
used for keys and not CertificateFactory
used for certificates.
这是代码,无需Base64转换,因为 CertificateFactory
可以读取PEM文件本身(它会查找 BEGIN/END CERTIFICATE
块本身来知道正在读取PEM文件).
Here's the code without Base64 conversion as CertificateFactory
can read PEM files itself (It looks for BEGIN/END CERTIFICATE
blocks itself to know that it's reading PEM file).
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
class LoadKey {
public static void main(String[] args)
throws Exception
{
String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM\n" +
"MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n" +
"THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x\n" +
"MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n" +
"MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n" +
"FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n" +
"gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy\n" +
"wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B\n" +
"d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM\n" +
"BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n" +
"LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n" +
"BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n" +
"Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n" +
"ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n" +
"AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp\n" +
"ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le\n" +
"IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==\n" +
"-----END CERTIFICATE-----\n";
System.out.println(cert);
byte[] certBytes = cert.getBytes(java.nio.charset.StandardCharsets.UTF_8);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(certBytes);
X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
System.out.println("Subject DN : " + certificate.getSubjectDN().getName());
System.out.println("Issuer : " + certificate.getIssuerDN().getName());
System.out.println("Not After: " + certificate.getNotAfter());
System.out.println("Not Before: " + certificate.getNotBefore());
System.out.println("version: " + certificate.getVersion());
System.out.println("serial number : " + certificate.getSerialNumber());
PublicKey publicKey = certificate.getPublicKey();
System.out.println("PublicKey : \n" + publicKey);
}
}
您缺少base64解码部分.参见上面的评论
这是工作代码,您需要 Apache Commons Codec Base64类的库.
Here's working code, you'll need Apache Commons Codec library for Base64 class.
注意::检查上面的代码,上面的base64步骤是由 CertificateFactory
自动完成的,无需手动进行.
Note: Check the code above, base64 steps above are done automatically by CertificateFactory
, there's no need to do it manually.
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.apache.commons.codec.binary.Base64;
class LoadKey {
public static void main(String[] args)
throws Exception
{
String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM\n" +
"MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n" +
"THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x\n" +
"MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n" +
"MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n" +
"FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n" +
"gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy\n" +
"wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B\n" +
"d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM\n" +
"BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n" +
"LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n" +
"BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n" +
"Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n" +
"ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n" +
"AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp\n" +
"ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le\n" +
"IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==\n" +
"-----END CERTIFICATE-----\n";
cert = cert.replace("-----BEGIN CERTIFICATE-----\n", "");
cert = cert.replace("-----END CERTIFICATE-----\n", "");
System.out.println(cert);
byte[] encodedCert = cert.getBytes("UTF-8");
byte[] decodedCert = Base64.decodeBase64(encodedCert);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(decodedCert);
X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
System.out.println("Subject DN : " + certificate.getSubjectDN().getName());
System.out.println("Issuer : " + certificate.getIssuerDN().getName());
System.out.println("Not After: " + certificate.getNotAfter());
System.out.println("Not Before: " + certificate.getNotBefore());
System.out.println("version: " + certificate.getVersion());
System.out.println("serial number : " + certificate.getSerialNumber());
PublicKey publicKey = certificate.getPublicKey();
System.out.println("PublicKey : \n" + publicKey);
}
}
输出
MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
Subject DN : CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
Issuer : CN=Thawte SGC CA, O=Thawte Consulting (Pty) Ltd., C=ZA
Not After: Mon Sep 30 19:59:59 EDT 2013
Not Before: Tue Oct 25 20:00:00 EDT 2011
version: 3
serial number : 105827261859531100510423749949966875981
PublicKey :
Sun RSA public key, 1024 bits
modulus: 156396091895984667473837837332877995558144703880815901117439532534031286131520903863087599986938779606924811933611903716377206837300122262900786662124968110191717844999183338594373129421417536020806373385428322642107305024162536996222164292639147591878860587271770855626780464602884552232097424473091745159379
public exponent: 65537
这篇关于无法从x509证书中提取公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!