
// 从文件加载证书
X509* load_certificate_from_file(const char* filename) {
BIO* bio = BIO_new_file(filename, "r");
if (!bio) {
fprintf(stderr, "Error opening certificate file: %s\n", filename);
return NULL;
}
X509* cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
BIO_free(bio);
if (!cert) {
fprintf(stderr, "Error reading certificate from: %s\n", filename);
}
return cert;
}
void print_certificate_details(X509* cert) {
if (!cert) {
fprintf(stderr, "Invalid certificate pointer\n");
return;
}
printf("\n=== 证书详细信息 ===\n");
// 1. 版本信息
printf("1. 版本: X509v%d\n", X509_get_version(cert) + 1);
// 2. 序列号
ASN1_INTEGER* serial = X509_get_serialNumber(cert);
if (serial) {
BIGNUM* bn = ASN1_INTEGER_to_BN(serial, NULL);
if (bn) {
char* serial_str = BN_bn2dec(bn);
printf("2. 序列号: %s\n", serial_str);
OPENSSL_free(serial_str);
BN_free(bn);
}
}
// 3. 签名算法
printf("3. 签名算法: ");
const ASN1_OBJECT* sig_alg_obj = X509_get0_tbs_sigalg(cert)->algorithm;
char sig_alg_buf[128];
OBJ_obj2txt(sig_alg_buf, sizeof(sig_alg_buf), sig_alg_obj, 1);
printf("%s\n", sig_alg_buf);
// 4. 颁发者信息
printf("4. 颁发者:\n");
X509_NAME* issuer = X509_get_issuer_name(cert);
if (issuer) {
for (int i = 0; i < X509_NAME_entry_count(issuer); i++) {
X509_NAME_ENTRY* entry = X509_NAME_get_entry(issuer, i);
ASN1_OBJECT* obj = X509_NAME_ENTRY_get_object(entry);
ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
char obj_buf[128];
OBJ_obj2txt(obj_buf, sizeof(obj_buf), obj, 0);
unsigned char* data_str = NULL;
int len = ASN1_STRING_to_UTF8(&data_str, data);
if (len > 0) {
printf(" %s: %s\n", obj_buf, data_str);
OPENSSL_free(data_str);
}
}
}
// 5. 有效期
printf("5. 有效期:\n");
ASN1_TIME* not_before = (ASN1_TIME*)X509_get0_notBefore(cert);
ASN1_TIME* not_after =(ASN1_TIME*) X509_get0_notAfter(cert);
if (not_before) {
BIO* bio = BIO_new(BIO_s_mem());
ASN1_TIME_print(bio, not_before);
char time_buf[256];
int len = BIO_read(bio, time_buf, sizeof(time_buf) - 1);
time_buf[len] = '\0';
printf(" 生效时间: %s\n", time_buf);
BIO_free(bio);
}
if (not_after) {
BIO* bio = BIO_new(BIO_s_mem());
ASN1_TIME_print(bio, not_after);
char time_buf[256];
int len = BIO_read(bio, time_buf, sizeof(time_buf) - 1);
time_buf[len] = '\0';
printf(" 过期时间: %s\n", time_buf);
BIO_free(bio);
}
// 6. 主体信息
printf("6. 主体:\n");
X509_NAME* subject = X509_get_subject_name(cert);
if (subject) {
for (int i = 0; i < X509_NAME_entry_count(subject); i++) {
X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject, i);
ASN1_OBJECT* obj = X509_NAME_ENTRY_get_object(entry);
ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
char obj_buf[128];
OBJ_obj2txt(obj_buf, sizeof(obj_buf), obj, 0);
unsigned char* data_str = NULL;
int len = ASN1_STRING_to_UTF8(&data_str, data);
if (len > 0) {
printf(" %s: %s\n", obj_buf, data_str);
OPENSSL_free(data_str);
}
}
}
// 7. 公钥信息
printf("7. 公钥信息:\n");
EVP_PKEY* pkey = X509_get_pubkey(cert);
if (pkey) {
int type = EVP_PKEY_id(pkey);
printf(" 算法: %s\n", OBJ_nid2ln(type));
int bits = EVP_PKEY_bits(pkey);
printf(" 密钥长度: %d bits\n", bits);
EVP_PKEY_free(pkey);
}
// 8. 扩展信息
printf("8. 扩展信息:\n");
int ext_count = X509_get_ext_count(cert);
for (int i = 0; i < ext_count; i++) {
X509_EXTENSION* ext = X509_get_ext(cert, i);
ASN1_OBJECT* obj = X509_EXTENSION_get_object(ext);
char ext_buf[128];
OBJ_obj2txt(ext_buf, sizeof(ext_buf), obj, 0);
printf(" %s", ext_buf);
// 显示关键扩展
if (X509_EXTENSION_get_critical(ext)) {
printf(" (关键)");
}
printf("\n");
// 显示特定扩展的详细信息
if (OBJ_obj2nid(obj) == NID_subject_alt_name) {
printf(" 主题备用名称: ");
BIO* bio = BIO_new(BIO_s_mem());
//X509V3_EXT_print(bio, ext, 0, 0);
//nmflag(名称显示标志)
X509_print_ex(bio, cert, XN_FLAG_COMPAT , X509_FLAG_NO_EXTENSIONS);
char ext_info[1024];
int len = BIO_read(bio, ext_info, sizeof(ext_info) - 1);
if (len > 0) {
ext_info[len] = '\0';
printf("%s", ext_info);
}
BIO_free(bio);
printf("\n");
}
}
// 9. 证书指纹
printf("9. 指纹:\n");
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int len;
if (X509_digest(cert, EVP_sha1(), md, &len)) {
printf(" SHA-1: ");
for (unsigned int i = 0; i < len; i++) {
printf("%02X", md[i]);
if (i < len - 1) printf(":");
}
printf("\n");
}
if (X509_digest(cert, EVP_sha256(), md, &len)) {
printf(" SHA-256: ");
for (unsigned int i = 0; i < len; i++) {
printf("%02X", md[i]);
if (i < len - 1) printf(":");
}
printf("\n");
}
printf("=== 证书信息结束 ===\n\n");
}
int openssl_rsa() {
X509 *x509=load_certificate_from_file("ca.crt");
print_certificate_details(x509);
return 0;
}