
// 从文件加载证书
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;
}