打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
OpenSSL对PEM证书解释
userphoto

2023.06.26 广东

关注

在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

通过上面信息我们可以看到,证书基本信息。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
发个我学习M2Crypto的笔记
rsa 加密算法_zh_new
PHP利用Socket获取网站的SSL证书与公钥
linux下使用openssl检测PE文件数字签名的证书是否有效
安装配置RabbitMQ(启动SSL)及测试案例
OpenSSL应用之公钥算法RSA
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服