当前位置: 首页 > 面试题库 >

无法从x509证书中提取公钥

东方修谨
2023-03-14
问题内容

这是我的代码:

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似乎并不喜欢它。

无论有没有尾随的\ n,我都已经厌倦了。

有任何想法吗?


问题答案:

- 更新

正如dave_thompson_085评论中提到的那样,OP解决方案唯一的问题是OP
KeyFactory使用的是密钥,而不是CertificateFactory证书。

这是 无需Base64转换 的代码 因为CertificateFactory它本身可以读取PEM文件(它会查找BEGIN/END CERTIFICATE块本身以知道它正在读取PEM文件)。

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解码部分。 见上面的评论

这是工作代码,您需要Base64类的Apache Commons
Codec
库。

注意: 检查上面的代码,上面的base64步骤是由自动完成的CertificateFactory,无需手动进行。

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


 类似资料:
  • 我是否能够使用Android或BouncyCastle libs从CA签名的X509客户端证书中提取证书链信息? 我有一个Android客户端,它从受信任的服务器接收CA签名的X509证书。我想将签名的客户端证书和我的私钥保存到PKCS12(. p12)文件中。我目前正在通过创建一个对象并添加证书和私钥来执行此操作。当我使用方法添加客户端时,是最后一个参数,它当前仅包含客户端证书。这是否会阻止我的

  • 我需要用DSA公钥验证X509证书签名。我的证书文件x509.crt,我的DSA公钥在一个名为dsa_pub.key的文件中 我正试图为此使用openssl。我已经阅读了openssl验证文档,但在其中找不到任何有关DSA的参考。 当我运行以下命令时,我可以在证书中看到我的DSA公钥: 但是,在使用文件DSA_pub.key中的DSA公钥验证cert.crt时,我遇到了麻烦 如果您有任何建议,我将

  • 对不起,我的错误,有两件事必须强调: 我正在尝试使用自签名证书作为HTTPS客户端证书。但是,存在一个问题“SSL:无法从对等证书获取公共名称” null 正在尝试127.0.0.1...已连接Enter PEM密码短语: 成功设置证书验证位置: cafile:/home/freeman/dev/git/ca_tools/ca_tools/ssl/ca/secure_ca.crt capath:/

  • 对于firebase生成的令牌的jwt令牌签名验证,firebase文档要求使用以下链接: https://www . Google APIs . com/robot/v1/metadata/x509/securetoken @ system . gserviceaccount . com 上面的链接给了我一个不是纯文本的Json,我如何从中解码和提取公钥? 对网络解码器有什么建议吗?

  • 过去,我一直在通过导出带有密码的PFX证书来制作安全的TcpListener,但我想知道是否可以跳过这一步。 我没有使用商业SSL证书,并且有一个根CA,用于颁发服务器证书。在C#中托管TcpListener时,这些服务器证书需要额外的步骤(我想是因为没有使用CSR)。。。但是如果我有私钥和OpenSSL生成/使用的证书呢。 这很好,但是我必须发出openssl命令,从证书和私钥生成pfx文件,然

  • 提前谢谢你