在PEM格式中,X.509格式证书是一种常见的证书格式。它是一个基于ASN.1数据格式的证书结构,在PEM格式下,通常以 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE----- 对包含在中间的编码数据进行标识。
X.509是一种公钥证书标准,如果你已经拥有一张X.509格式的证书,它就包含以下信息:
- 证书的颁发者和使用者的区别名(DN);
- 公钥和私钥;
- 证书的版本号;
- 证书的序列号;
- 证书的有效期限;
- 签名算法和签名值。
PEM是一种常见的证书编码方式,它使用base64编码将二进制的X.509格式证书进行编码,再使用ASCII字符加上起始和结束标记,即 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE-----,加入换行符等标记符号来标识证书数据。因为PEM格式以ASCII字符为基础编码,因此它更容易用文本编辑器处理和传输。
在使用PEM编码的X.509证书时,可以通过文件扩展名为 .pem 或 .crt 来标识。此外,PEM格式的证书还可以使用其他类型的标准格式转换,例如DER格式、PKCS#7格式等。
总之,PEM编码的X.509格式证书是一种最常见的证书格式之一,它具有简单、易读、易转换的特点,被广泛应用于HTTPS、TLS、SSL、SSH等系统中。
下面我用OpenSSL库来对证书进行解释:
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <stdlib.h> #include <unistd.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <netdb.h> #include <openssl/x509.h> #include <openssl/x509v3.h> #include <openssl/bio.h> void printHex(const char *title, unsigned char *buffer, long size) { int i; printf("%s :\n",title); for(i=0;i<size;i++) { /*if(i%16 == 0) printf("\n");*/ printf("%02X", buffer[i]); } printf("\n"); } void ShowCerts(SSL * ssl) { X509 *cert; char *line; cert = SSL_get_peer_certificate(ssl); if (cert != NULL) { printf("cer info :\n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("subject : %s\n", line); free(line); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("issuer: %s\n", line); free(line); X509_free(cert); } else { printf("no info!\n"); } } void parseCert(X509* x509) { BIO *bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); long l = X509_get_version(x509); BIO_printf(bio_out, "Version: %ld\n", l+1); ASN1_INTEGER *bs = X509_get_serialNumber(x509); BIO_printf(bio_out,"Serial: "); for(int i=0; i<bs->length; i++) { BIO_printf(bio_out,"%02x",bs->data[i] ); } BIO_printf(bio_out,"\n"); X509_signature_print(bio_out, x509->sig_alg, NULL); BIO_printf(bio_out,"Issuer: "); X509_NAME_print(bio_out,X509_get_issuer_name(x509),0); BIO_printf(bio_out,"\n"); BIO_printf(bio_out,"Valid From: "); ASN1_TIME_print(bio_out,X509_get_notBefore(x509)); BIO_printf(bio_out,"\n"); BIO_printf(bio_out,"Valid Until: "); ASN1_TIME_print(bio_out,X509_get_notAfter(x509)); BIO_printf(bio_out,"\n"); BIO_printf(bio_out,"Subject: "); X509_NAME_print(bio_out,X509_get_subject_name(x509),0); BIO_printf(bio_out,"\n"); EVP_PKEY *pkey=X509_get_pubkey(x509); EVP_PKEY_print_public(bio_out, pkey, 0, NULL); EVP_PKEY_free(pkey); X509_CINF *ci=x509->cert_info; X509V3_extensions_print(bio_out, (char*)"X509v3 extensions", ci->extensions, X509_FLAG_COMPAT, 0); X509_signature_print(bio_out, x509->sig_alg, x509->signature); BIO_free(bio_out); } int public_key_size(X509 *x509) { EVP_PKEY *pkey=X509_get_pubkey(x509); int key_type = EVP_PKEY_type(pkey->type); int keysize = -1; //or in bytes, RSA_size() DSA_size(), DH_size(), ECDSA_size(); keysize = key_type==EVP_PKEY_RSA && pkey->pkey.rsa->n ? BN_num_bits(pkey->pkey.rsa->n) : keysize; keysize = key_type==EVP_PKEY_DSA && pkey->pkey.dsa->p ? BN_num_bits(pkey->pkey.dsa->p) : keysize; keysize = key_type==EVP_PKEY_DH && pkey->pkey.dh->p ? BN_num_bits(pkey->pkey.dh->p) : keysize; keysize = key_type==EVP_PKEY_EC ? EC_GROUP_get_degree(EC_KEY_get0_group(pkey->pkey.ec)) : keysize; printf("keysize =%d\n", keysize); EVP_PKEY_free(pkey); return keysize; } char * public_key_type(X509 *x509) { EVP_PKEY *pkey=X509_get_pubkey(x509); int key_type = EVP_PKEY_type(pkey->type); EVP_PKEY_free(pkey); if (key_type==EVP_PKEY_RSA) return "RSA"; if (key_type==EVP_PKEY_DSA) return "DSA"; if (key_type==EVP_PKEY_DH) return "DH"; if (key_type==EVP_PKEY_EC) return "ECC"; return "NULL"; } int read_pemcert(const char * path) { char *line; FILE *fp = fopen(path, "r"); if (!fp) { fprintf(stderr, "unable to open: %s\n", path); return EXIT_FAILURE; } printf("open cert file %s\n", path); X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL); if (!cert) { fprintf(stderr, "unable to parse certificate in: %s\n", path); fclose(fp); return EXIT_FAILURE; } if (cert != NULL) { printf("cer info :\n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("subject : %s\n", line); free(line); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("issuer: %s\n", line); free(line); // 获取证书的签名算法ID int nid = X509_get_signature_nid(cert); printf("nid=%d\r\n", nid); // 提取证书的公钥 EVP_PKEY *pkey = X509_get_pubkey(cert); printf( "public_key_type =%s\n", public_key_type(cert)); public_key_size(cert); parseCert(cert); free(pkey); } else printf("no info!\n"); // any additional processing would go here.. //exits: //X509_free(cert); X509_free(cert); fclose(fp); return 0; } int main(int argc, char **argv) { if (argc < 2) { printf("Usage:pem_info [pem]\n"); exit(0); } read_pemcert(argv[1]); return 0; }
执行结果:
wythe@xxxx:~/linux-sys/tls$ ./pem_info CAcert.pem open cert file CAcert.pem cer info : subject : /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd issuer: /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd nid=668 public_key_type =RSA keysize =2048 Version: 3 Serial: b10934b71e25a831 Signature Algorithm: sha256WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Valid From: Aug 9 06:39:06 2022 GMT Valid Until: Aug 8 06:39:06 2025 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Public-Key: (2048 bit) Modulus: 00:c4:51:82:83:dc:72:ef:78:52:44:e1:a7:52:df: 4d:0d:77:63:a8:a3:72:54:81:1e:14:2f:6e:5a:c0: f9:df:23:fe:50:c5:c9:50:6f:02:12:7a:5e:38:b4: f8:95:11:5c:7f:99:6d:69:c5:c1:0b:c5:34:7a:19: b8:f7:6a:5c:1f:8f:9d:26:be:f1:16:27:82:ce:d7: c2:6c:6a:66:56:52:65:7c:4b:08:9a:8b:62:f1:e0: 59:98:ed:ef:58:99:70:16:a3:b5:10:98:19:92:c8: cf:05:ba:01:09:98:cb:d3:44:6a:aa:68:78:0d:e7: 96:55:bd:b2:0e:3d:90:bc:35:52:8a:d3:bb:c5:0a: f7:cd:96:13:a8:bc:1a:f3:96:ff:90:80:a8:e7:d4: 91:4c:ef:cf:7f:07:01:36:0b:57:df:9f:ca:d9:7a: 8d:93:c7:19:35:c5:e3:cf:d3:8b:ed:62:e9:0b:e2: a0:d0:e1:77:fd:fe:1b:d0:67:23:ea:11:03:f8:88: 60:8f:bc:ae:8e:10:85:bc:11:b2:b9:b8:58:f1:64: 4e:36:a4:82:11:93:85:7f:cb:a3:7b:bb:c0:13:7b: 7e:9b:24:f6:ca:46:75:f1:a4:07:79:c7:b3:bb:29: 6f:33:2d:d2:b9:98:ab:c0:24:96:9d:1c:e8:40:93: 7b:35 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 28:85:D5:0E:2F:A7:36:18:8B:1A:1E:94:97:E0:36:5E:FA:EE:A7:FD X509v3 Authority Key Identifier: keyid:28:85:D5:0E:2F:A7:36:18:8B:1A:1E:94:97:E0:36:5E:FA:EE:A7:FD X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha256WithRSAEncryption 5b:ab:d1:41:31:da:93:1b:8d:4c:7a:83:62:e1:ff:2c:0d:f0: 74:7e:60:0a:28:c8:96:44:0c:ce:37:e3:ef:65:6b:0b:63:e6: 4f:4c:84:81:fa:ec:84:95:57:be:6a:c1:76:54:97:3d:86:ea: a4:67:c6:e1:22:95:e0:c8:5f:89:08:aa:79:cf:27:83:99:de: 5a:8e:ee:59:0d:fe:2a:81:71:24:d4:e5:eb:b5:33:66:9d:91: 39:72:3e:22:bd:21:e0:78:c4:b6:dc:20:20:6e:54:be:4d:5a: d3:1d:2b:2d:e7:35:87:e5:cf:8c:83:aa:14:6f:b2:1d:4c:48: 9a:a8:57:2a:74:d1:42:3b:b4:1a:fa:88:d8:2f:4e:4c:5b:34: 18:8d:9e:0b:1e:19:4d:36:86:62:cb:76:26:76:c3:6c:c1:83: 18:b8:5a:1d:42:a2:b5:f8:43:94:7f:31:48:b7:9a:15:b3:dd: 9a:54:17:e8:2e:a1:ac:50:cf:4d:03:70:12:b4:55:82:40:c0: b2:46:3f:33:f2:4c:f5:a3:2e:18:ca:3b:cf:50:1a:30:7b:52: 0c:19:a0:2b:98:33:1f:22:c5:3d:0d:59:54:33:64:93:93:b6: 10:a4:9f:77:17:4a:bd:b0:c2:71:99:61:2e:8d:1a:6f:f6:ea: dd:4b:47:45
通过上面信息我们可以看到,证书基本信息。
联系客服