美文网首页
关于X509证书

关于X509证书

作者: GTMYang | 来源:发表于2023-08-27 15:44 被阅读0次

    X509简介

    • X.509证书是一种数字证书标准,用于验证在计算机网络中的身份认证。它们是
      由权威机构(例如CA)发行,包含有关证书持有者身份信息的数字签名。
    • X.509证书通常用于SSL / TLS协议,以确保客户端和服务器之间的安全数据传输。当您访问一个网站时,浏览器会向服务器请求其证书,并且如果该证书通过了验证,就可以建立加密连接。该证书包含了网站所有者的名称、证书颁发机构的名称、有效期限、公钥等信息。
    • 具体来说,X.509证书包括以下主要部分:
        证书颁发机构信息
        证书持有人信息
        公钥
        签名
    
    • 其中,签名是最重要的部分,它用于验证证书是否真实有效。在验证证书时,浏览器将使用相应的公钥对证书进行解密并检查签名是否正确。如果签名被篡改或证书已过期,则将不会建立安全连接。
    • X.509是公钥基础设施(PKI)的一部分,它定义了证书的格式和内容。PKI我们之前提到过是一种安全框架,用于管理数字证书的创建、存储、传递和验证。X.509是PKI中最重要的标准之一,它定义了数字证书的结构和内容,并确保数字证书的安全性和可靠性。

    X509在java中的表现形式

    • 在Java中,X.509数字证书通常使用java.security.cert.X509Certificate类表示。该类是Java Cryptography Architecture(JCA)的一部分,提供了一些用于处理数字证书的方法。
    • 我们可以看到该类是一个抽象类,不能直接实例化,要么通过其他方法获取该类,要么使用具体的子类进行实例化。
    • 通常情况下,可以使用Java SE提供的默认实现类java.security.cert.X509CertificateImpl来创建X.509证书对象。这个类是X509Certificate的默认实现,并提供了各种方法来对证书进行操作和管理。
    • 当你调用X509Certificate.getInstance()方法时,在不指定具体实现类的情况下,Java会自动选择最适合当前环境的默认实现类进行实例化。在大多数情况下,这个默认实现类就是java.security.cert.X509CertificateImpl。
    • 我们一般通过CertificateFactory.generateCertificate()去创建X509Certificate,我们首先需要X509证书文件或者X509证书的Base64串,比如我一般更喜欢通过X509证书的Base64串去生成X509Certificate,代码如下:
    String rootCert = "MIIFuDCCBKCgAwIBAgIQche7n/HhSQ+guIZEOjNvGzANBgkqhkiG9w0BAQsFADAzMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxETAPBgNVBAMMCFNIRUNBIEcyMB4XDTIzMDIwNTE3MDQ0MVoXDTIzMDUwNjE1NTk1OVowTzELMAkGA1UEBhMCQ04xGzAZBgNVBAoMEueUteWtkOetvueroOWJjeWPsDEjMCEGA1UEAwwa5rWL6K+VMDEwMTExMUA4NCoqKioqKioqMjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCHJ8088uY9p4XD77TrLu3h0tB5O4Xp32hW4zNttjHmhoXai7wngFooNXDzGwj9JnM99VE+qjQzkr8Th9pyIYeTk5eLTMmmMEo/p42uiHyGbTtn8B2g3wmPTApu2S4+MAkNbvPD5VDEfMb+1e/7oN39NTZv1mBoENpst6nwEdgQ7jla4ueOcKOWWmFT+3lGzx3tWm8lkqSnryaSjNtMynMK25PxiXLFV8dQ4Wk7DigQpveP+GH8ltTHoZqpZMcXy5qgUWeZSfNYQ1i3JajjKBdSzflrKBi3HeeQBzPSk6M12B6EE5usl1zCABXl6o29IREEy9d/zmmScyLtff+oYw19AgMBAAGjggKqMIICpjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwfQYIKwYBBQUHAQEEcTBvMDgGCCsGAQUFBzABhixodHRwOi8vb2NzcDMuc2hlY2EuY29tL29jc3Avc2hlY2Evc2hlY2Eub2NzcDAzBggrBgEFBQcwAoYnaHR0cDovL2xkYXAyLnNoZWNhLmNvbS9yb290L3NoZWNhZzIuZGVyMB8GA1UdIwQYMBaAFFaI3uMYQ4K3cqQm60SpYtCHxKwmMB0GA1UdDgQWBBS8nQ//lcMctfZGZ1AnPCwwRPZM6TALBgNVHQ8EBAMCBsAwgYYGBiqBHAHFOAR8MHowSQYIKoEcAcU4gRAEPWxkYXA6Ly9sZGFwMi5zaGVjYS5jb20vb3U9c2hlY2EgY2VydGlmaWNhdGUgY2hhaW4sbz1zaGVjYS5jb20wEQYIKoEcAcU4gRMEBTY2MDU1MBoGCCqBHAHFOIEUBA5RVDg0OTAyMzc0MDkyMzAJBgNVHRMEAjAAMEIGA1UdIAQ7MDkwNwYJKoEcAYbvOoEVMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly93d3cuc2hlY2EuY29tL3BvbGljeS8wgeAGA1UdHwSB2DCB1TA3oDWgM4YxaHR0cDovL2xkYXAyLnNoZWNhLmNvbS9DQTIwMDExL1JBOTAzMS9DUkw1MTkxLmNybDCBmaCBlqCBk4aBkGxkYXA6Ly9sZGFwMi5zaGVjYS5jb206Mzg5L2NuPUNSTDUxOTEuY3JsLG91PVJBOTAzMSxvdT1DQTIwMDExLG91PWNybCxvPVVuaVRydXN0P2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDANBgkqhkiG9w0BAQsFAAOCAQEAjQRnIYRE9SH4+leOjO9oUt++qhfefVzaZXdGQgxiUzIXv14vo9mls0COjz0YXoruEe6olh6X6rrdmaKrYw0iq2CJ3D1GkrFCutjX2P3r97Irale8w5J8hJ6dybd/rFZFZuTfYm7yWJLEcF+pAZXedGObwe4fOjS0J/A6KXqGsrdB/fJwvfHH5UIIWW3OihTr1TLEEuun/3oDbGdBDTud2+6tbiEN9daFV92TSko2DRQ/CisJoq5SCmI/dYZlAqeyr4jlLWHFfVUpHKuvpn/lHtYCU0FsGyu9ixs4/YdBw/QIDj5oES9yf/FFDzfTnS8twa8rRJKWdUKKa9sYEeJtVQ==";
    CertificateFactory cf = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
    X509Certificate certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64Utils.decode(rootCert)));
    // 当然你也可以通过X509文件形式去生成,代码如下:
    public static void main(String[] args) throws Exception {
        String certificateFileName = "C:\Users\Administrator\Downloads\user.cer";
        FileInputStream inputStream = new FileInputStream(certificateFileName);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
    }
    
    • 这里说一下X509文件一般使用的后缀:
      X509证书文件一般使用以下文件后缀名:
      . pem
      . crt
      . cer
      . der
      这些后缀名的具体使用取决于证书文件所包含的数据类型和编码方式。例如,.pem格式的证书是以Base64编码的ASCII文本格式,.crt格式的证书通常是PEM编码的,而.cer格式的证书可以是DER编码或PEM编码。

    X509Certificate的一些常用接口

    X509Certificate.getSerialNumber()

    getSerialNumber()方法是用于获取证书的序列号的方法。
    X.509证书的序列号是一个唯一标识符,用于区分不同证书之间的差异。通常情况下,证书颁发机构(CA)会为每个证书生成一个唯一的序列号,并将这个序列号嵌入到证书中。在使用证书进行身份验证时,可以通过比较证书序列号来确定证书是否有效,以及它是否由可信的CA签发。
    getSerialNumber()方法返回一个BigInteger对象,该对象包含证书的序列号。开发者可以使用这个方法来检索证书的序列号,并进一步对证书进行身份验证和授权操作。
    总之,X509Certificate.getSerialNumber()方法是一个用于获取X.509证书序列号的实用方法,在进行证书验证和授权操作时非常有用。
    既然说到了序列号,我们额外提一嘴。
    不同CA对序列号的生成方式各不相同,我们一般是通过CertificateSerialNumber去创建一个序列号,该类接收一个BigInteger类型的参数。

    getIssuerDN()和getIssuerX500Principal()
    • X509Certificate.getIssuerDN()方法是用于获取X.509证书的颁发者(Issuer)的DN信息。
    • 在Java中,X.509证书是一种常见的数字证书格式,它包含了公钥、持有人的身份信息以及其他相关信息。其中,颁发者信息是证书的重要组成部分之一,它描述了颁发该证书的机构或个人的身份和详细信息,如国家/地区、组织名称等。
    • getIssuerDN()方法返回一个Principal对象,该对象封装了证书颁发者的DN信息,即一个字符串序列,其中包含DN的各个字段及其对应的值。开发人员可以通过调用Principal的getName()方法来获取DN信息的字符串表示形式,从而查看证书的颁发者信息。
    • 而颁发者DN比较重要的一点就是在于验证根证书的时候,我们知道,在证书链中,每个数字证书的颁发者DN必须与下一个数字证书的主题DN相匹配。根证书作为证书链的最后一个证书,它的颁发者DN应该与其自身的主题DN相匹配。这样才能确保证书链的完整性和有效性。
      可能有些小伙伴会发现除了getIssuerDN()之外还有一个getIssuerX500Principal()方法,其实大家运行后会发现两者返回的DN信息其实是一致的,只是顺序可能不一样。他们两个方法的区别就在于返回类型的不同,getIssuerDN()返回类型为Principal,而getIssuerX500Principal()返回X500Principal,它是Java安全API中定义的一种标准类型的X.500 Principal类型。这个对象也可以被用于进一步处理和解析DN中的属性,但是其主要优势是可以直接用于与其他Java API中的X.500 Principal类型集成。
      X500Principal可以看作是Principal的一个具体实现,专门用于处理X.500格式的DN。它包含了X.500格式的字符串表示形式,并提供了一些与X.500 DN相关的方法,例如:getName()、getEncoded()等。
      理解了这个,后面的getSubjectDN()和getSubjectX500Principal()的区别想必也不难理解
    getSubjectDN()和getSubjectX500Principal()

    X509Certificate.getSubjectDN() 是 Java 中 X.509 证书(一种常见的公钥证书格式)类 X509Certificate 的一个方法。它返回证书主体的 Distinguished Name(简称 DN),即证书中标识持有者身份信息的部分。和之前的getIssueDn不同的是,前者是证书持有者,后者是证书颁发者。
    例如,假设 A 公司的网站使用了一张由 B CA 签发的 X.509 数字证书,那么该证书的 subject DN 中会包含 A 公司的相关信息,issuer DN 中会包含 B CA 的相关信息。调用 getSubjectDN() 方法可以获取到 A 公司的身份信息,调用 getIssuerDN() 方法可以获取到 B CA 的身份信息。
    DN 通常由多个相互独立的字段组成,这些字段采用键值对的方式描述了证书持有者的重要信息。例如,一个包含 CN、OU、O、L、ST、EMAILADDRESS 和 C 字段的 DN 可以表示一个具体的人或实体,如下所示:

    CN=xxx@xxx, OU=Organize Unit, O=Organize Ltd., L=city, ST=privince, EMAILADDRESS= xxxx@xxx.com,C=CN
    

    其中,CN 表示 Common Name,即常用名称,代表证书持有者的姓名或实体名;OU 表示 Organizational Unit,即组织单位,代表证书持有者所在的组织或部门;O 表示 Organization,即组织机构,代表证书持有者所属的公司或机构;L 表示 Locality,即所在地,代表证书持有者所在的城市或地区;ST 表示 State,即省份或州,代表证书持有者所在的省份或州;EMAILADDRESS 表示邮件地址;C 表示 Country,即国家或地区,代表证书持有者所在的国家或地区。
    通过调用 X509Certificate.getSubjectDN() 方法,我们可以获取到证书中标识持有者身份信息的所有字段及其值,以便进行身份验证或授权等操作。
    而getSubjectX500Principal()和getIssuerX500Principal()本质上是一样的,这里不做赘述
    以下是测试代码:

    public static void main(String[] args) throws GeneralSecurityException, IOException, OperatorException, OCSPException {
    String verifyCert = "MIIFuDCCBKCgAwIBAgIQche7n/HhSQ+guIZEOjNvGzANBgkqhkiG9w0BAQsFADAzMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxETAPBgNVBAMMCFNIRUNBIEcyMB4XDTIzMDIwNTE3MDQ0MVoXDTIzMDUwNjE1NTk1OVowTzELMAkGA1UEBhMCQ04xGzAZBgNVBAoMEueUteWtkOetvueroOWJjeWPsDEjMCEGA1UEAwwa5rWL6K+VMDEwMTExMUA4NCoqKioqKioqMjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCHJ8088uY9p4XD77TrLu3h0tB5O4Xp32hW4zNttjHmhoXai7wngFooNXDzGwj9JnM99VE+qjQzkr8Th9pyIYeTk5eLTMmmMEo/p42uiHyGbTtn8B2g3wmPTApu2S4+MAkNbvPD5VDEfMb+1e/7oN39NTZv1mBoENpst6nwEdgQ7jla4ueOcKOWWmFT+3lGzx3tWm8lkqSnryaSjNtMynMK25PxiXLFV8dQ4Wk7DigQpveP+GH8ltTHoZqpZMcXy5qgUWeZSfNYQ1i3JajjKBdSzflrKBi3HeeQBzPSk6M12B6EE5usl1zCABXl6o29IREEy9d/zmmScyLtff+oYw19AgMBAAGjggKqMIICpjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwfQYIKwYBBQUHAQEEcTBvMDgGCCsGAQUFBzABhixodHRwOi8vb2NzcDMuc2hlY2EuY29tL29jc3Avc2hlY2Evc2hlY2Eub2NzcDAzBggrBgEFBQcwAoYnaHR0cDovL2xkYXAyLnNoZWNhLmNvbS9yb290L3NoZWNhZzIuZGVyMB8GA1UdIwQYMBaAFFaI3uMYQ4K3cqQm60SpYtCHxKwmMB0GA1UdDgQWBBS8nQ//lcMctfZGZ1AnPCwwRPZM6TALBgNVHQ8EBAMCBsAwgYYGBiqBHAHFOAR8MHowSQYIKoEcAcU4gRAEPWxkYXA6Ly9sZGFwMi5zaGVjYS5jb20vb3U9c2hlY2EgY2VydGlmaWNhdGUgY2hhaW4sbz1zaGVjYS5jb20wEQYIKoEcAcU4gRMEBTY2MDU1MBoGCCqBHAHFOIEUBA5RVDg0OTAyMzc0MDkyMzAJBgNVHRMEAjAAMEIGA1UdIAQ7MDkwNwYJKoEcAYbvOoEVMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly93d3cuc2hlY2EuY29tL3BvbGljeS8wgeAGA1UdHwSB2DCB1TA3oDWgM4YxaHR0cDovL2xkYXAyLnNoZWNhLmNvbS9DQTIwMDExL1JBOTAzMS9DUkw1MTkxLmNybDCBmaCBlqCBk4aBkGxkYXA6Ly9sZGFwMi5zaGVjYS5jb206Mzg5L2NuPUNSTDUxOTEuY3JsLG91PVJBOTAzMSxvdT1DQTIwMDExLG91PWNybCxvPVVuaVRydXN0P2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDANBgkqhkiG9w0BAQsFAAOCAQEAjQRnIYRE9SH4+leOjO9oUt++qhfefVzaZXdGQgxiUzIXv14vo9mls0COjz0YXoruEe6olh6X6rrdmaKrYw0iq2CJ3D1GkrFCutjX2P3r97Irale8w5J8hJ6dybd/rFZFZuTfYm7yWJLEcF+pAZXedGObwe4fOjS0J/A6KXqGsrdB/fJwvfHH5UIIWW3OihTr1TLEEuun/3oDbGdBDTud2+6tbiEN9daFV92TSko2DRQ/CisJoq5SCmI/dYZlAqeyr4jlLWHFfVUpHKuvpn/lHtYCU0FsGyu9ixs4/YdBw/QIDj5oES9yf/FFDzfTnS8twa8rRJKWdUKKa9sYEeJtVQ==";
    CertificateFactory cf = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
    X509Certificate certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64Utils.decode(verifyCert)));
    System.out.println(certificate.getSubjectDN());
    System.out.println(certificate.getSubjectX500Principal());
    }
    
    getNotBefore()和getNotAfter()
    • getNotBefore()和getNotAfter()是Java中X.509证书类(java.security.cert.X509Certificate)的方法,用于获取证书的生效日期和过期日期。两者均返回Date类型
    • getNotBefore()方法返回证书的生效日期,它表示自1970年1月1日00:00:00 GMT以来的毫秒数。这个时间点之前,证书被认为是无效的。例如,如果getNotBefore()返回的值是1618476000000,那么证书的生效日期是2021年4月15日00:00:00 GMT。
    • getNotAfter()方法返回证书的过期日期,它也表示自1970年1月1日00:00:00 GMT以来的毫秒数。这个时间点之后,证书将被认为是无效的。例如,如果getNotAfter()返回的值是1649992800000,那么证书的过期日期是2023年4月14日23:59:59 GMT。
      这些方法可用于验证证书是否在其生命周期内,并且可以帮助确定何时需要更新证书。

    相关文章

      网友评论

          本文标题:关于X509证书

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