openssl 证书解析
程序员文章站
2022-03-06 18:57:46
...
简单实用例子 openssl 解析x509证书
命令行打印证书细节: openssl x509 -noout -text -in cert.crt
sudo apt-get install libssl-dev #debian based
yum install openssl-devel #redhat based
compile...
g++ main.cpp -o main -lcrypto
main.cpp
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
using std::cout;
using std::endl;
using std::stringstream;
using std::map;
using std::vector;
using std::string;
//----------------------------------------------------------------------
string thumbprint(X509* x509)
{
static const char hexbytes[] = "0123456789ABCDEF";
unsigned int md_size;
unsigned char md[EVP_MAX_MD_SIZE];
const EVP_MD * digest = EVP_get_digestbyname("sha1");
X509_digest(x509, digest, md, &md_size);
stringstream ashex;
for(int pos = 0; pos < md_size; pos++)
{
ashex << hexbytes[ (md[pos]&0xf0)>>4 ];
ashex << hexbytes[ (md[pos]&0x0f)>>0 ];
}
return ashex.str();
}
//----------------------------------------------------------------------
int certversion(X509* x509)
{
return X509_get_version(x509) +1;
}
//----------------------------------------------------------------------
string pem(X509* x509)
{
BIO * bio_out = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio_out, x509);
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
string pem = string(bio_buf->data, bio_buf->length);
BIO_free(bio_out);
return pem;
}
//----------------------------------------------------------------------
void _asn1dateparse(const ASN1_TIME *time, int& year, int& month, int& day, int& hour, int& minute, int& second)
{
const char* str = (const char*) time->data;
size_t i = 0;
if (time->type == V_ASN1_UTCTIME) {/* two digit year */
year = (str[i++] - '0') * 10;
year += (str[i++] - '0');
year += (year < 70 ? 2000 : 1900);
} else if (time->type == V_ASN1_GENERALIZEDTIME) {/* four digit year */
year = (str[i++] - '0') * 1000;
year+= (str[i++] - '0') * 100;
year+= (str[i++] - '0') * 10;
year+= (str[i++] - '0');
}
month = (str[i++] - '0') * 10;
month += (str[i++] - '0') - 1; // -1 since January is 0 not 1.
day = (str[i++] - '0') * 10;
day += (str[i++] - '0');
hour = (str[i++] - '0') * 10;
hour+= (str[i++] - '0');
minute = (str[i++] - '0') * 10;
minute += (str[i++] - '0');
second = (str[i++] - '0') * 10;
second += (str[i++] - '0');
}
//----------------------------------------------------------------------
string _asn1int(ASN1_INTEGER *bs)
{
static const char hexbytes[] = "0123456789ABCDEF";
stringstream ashex;
for(int i=0; i<bs->length; i++)
{
ashex << hexbytes[ (bs->data[i]&0xf0)>>4 ] ;
ashex << hexbytes[ (bs->data[i]&0x0f)>>0 ] ;
}
return ashex.str();
}
//----------------------------------------------------------------------
string _asn1string(ASN1_STRING *d)
{
string asn1_string;
if (ASN1_STRING_type(d) != V_ASN1_UTF8STRING) {
unsigned char *utf8;
int length = ASN1_STRING_to_UTF8( &utf8, d );
asn1_string= string( (char*)utf8, length );
OPENSSL_free( utf8 );
} else {
asn1_string= string( (char*)ASN1_STRING_data(d), ASN1_STRING_length(d) );
}
return asn1_string;
}
//----------------------------------------------------------------------
string _subject_as_line(X509_NAME *subj_or_issuer)
{
BIO * bio_out = BIO_new(BIO_s_mem());
X509_NAME_print(bio_out,subj_or_issuer,0);
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
string issuer = string(bio_buf->data, bio_buf->length);
BIO_free(bio_out);
return issuer;
}
//----------------------------------------------------------------------
std::map<string,string> _subject_as_map(X509_NAME *subj_or_issuer)
{
std::map<string,string> m;
for (int i = 0; i < X509_NAME_entry_count(subj_or_issuer); i++) {
X509_NAME_ENTRY *e = X509_NAME_get_entry(subj_or_issuer, i);
ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
ASN1_OBJECT *o = X509_NAME_ENTRY_get_object(e);
const char* key_name = OBJ_nid2sn( OBJ_obj2nid( o ) );
m[key_name] = _asn1string(d);
}
return m;
}
//----------------------------------------------------------------------
string issuer_one_line(X509* x509)
{
return _subject_as_line(X509_get_issuer_name(x509));
}
//----------------------------------------------------------------------
string subject_one_line(X509* x509)
{
return _subject_as_line(X509_get_subject_name(x509));
}
//----------------------------------------------------------------------
std::map<string,string> subject(X509* x509)
{
return _subject_as_map(X509_get_subject_name(x509));
}
//----------------------------------------------------------------------
std::map<string,string> issuer(X509* x509)
{
return _subject_as_map(X509_get_issuer_name(x509));
}
//----------------------------------------------------------------------
string serial(X509* x509)
{
return _asn1int(X509_get_serialNumber(x509));
}
//----------------------------------------------------------------------
string signature_algorithm(X509 *x509)
{
int sig_nid = OBJ_obj2nid((x509)->sig_alg->algorithm);
return string( OBJ_nid2ln(sig_nid) );
}
//----------------------------------------------------------------------
string 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 "";
}
//----------------------------------------------------------------------
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;
EVP_PKEY_free(pkey);
return keysize;
}
//----------------------------------------------------------------------
string public_key_ec_curve_name(X509 *x509)
{
EVP_PKEY *pkey=X509_get_pubkey(x509);
int key_type = EVP_PKEY_type(pkey->type);
if (key_type==EVP_PKEY_EC)
{
const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
int name = (group != NULL) ? EC_GROUP_get_curve_name(group) : 0;
return name ? OBJ_nid2sn(name) : "";
}
return "";
}
//----------------------------------------------------------------------
string asn1datetime_isodatetime(const ASN1_TIME *tm)
{
int year=0, month=0, day=0, hour=0, min=0, sec=0;
_asn1dateparse(tm,year,month,day,hour,min,sec);
char buf[25]="";
snprintf(buf, sizeof(buf)-1, "%04d-%02d-%02d %02d:%02d:%02d GMT", year, month, day, hour, min, sec);
return string(buf);
}
//----------------------------------------------------------------------
string asn1date_isodate(const ASN1_TIME *tm)
{
int year=0, month=0, day=0, hour=0, min=0, sec=0;
_asn1dateparse(tm,year,month,day,hour,min,sec);
char buf[25]="";
snprintf(buf, sizeof(buf)-1, "%04d-%02d-%02d", year, month, day);
return string(buf);
}
//----------------------------------------------------------------------
vector<string> subject_alt_names(X509 *x509)
{
vector<string> list;
GENERAL_NAMES* subjectAltNames = (GENERAL_NAMES*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
for (int i = 0; i < sk_GENERAL_NAME_num(subjectAltNames); i++)
{
GENERAL_NAME* gen = sk_GENERAL_NAME_value(subjectAltNames, i);
if (gen->type == GEN_URI || gen->type == GEN_DNS || gen->type == GEN_EMAIL)
{
ASN1_IA5STRING *asn1_str = gen->d.uniformResourceIdentifier;
string san = string( (char*)ASN1_STRING_data(asn1_str), ASN1_STRING_length(asn1_str) );
list.push_back( san );
}
else if (gen->type == GEN_IPADD)
{
unsigned char *p = gen->d.ip->data;
if(gen->d.ip->length == 4)
{
stringstream ip;
ip << (int)p[0] << '.' << (int)p[1] << '.' << (int)p[2] << '.' << (int)p[3];
list.push_back( ip.str() );
}
else //if(gen->d.ip->length == 16) //ipv6?
{
//std::cerr << "Not implemented: parse sans ("<< __FILE__ << ":" << __LINE__ << ")" << endl;
}
}
else
{
//std::cerr << "Not implemented: parse sans ("<< __FILE__ << ":" << __LINE__ << ")" << endl;
}
}
GENERAL_NAMES_free(subjectAltNames);
return list;
}
//----------------------------------------------------------------------
vector<string> ocsp_urls(X509 *x509)
{
vector<string> list;
STACK_OF(OPENSSL_STRING) *ocsp_list = X509_get1_ocsp(x509);
for (int j = 0; j < sk_OPENSSL_STRING_num(ocsp_list); j++)
{
list.push_back( string( sk_OPENSSL_STRING_value(ocsp_list, j) ) );
}
X509_email_free(ocsp_list);
return list;
}
//----------------------------------------------------------------------
vector<string> crl_urls(X509 *x509)
{
vector<string> list;
int nid = NID_crl_distribution_points;
STACK_OF(DIST_POINT) * dist_points =(STACK_OF(DIST_POINT) *)X509_get_ext_d2i(x509, nid, NULL, NULL);
for (int j = 0; j < sk_DIST_POINT_num(dist_points); j++)
{
DIST_POINT *dp = sk_DIST_POINT_value(dist_points, j);
DIST_POINT_NAME *distpoint = dp->distpoint;
if (distpoint->type==0)//fullname GENERALIZEDNAME
{
for (int k = 0; k < sk_GENERAL_NAME_num(distpoint->name.fullname); k++)
{
GENERAL_NAME *gen = sk_GENERAL_NAME_value(distpoint->name.fullname, k);
ASN1_IA5STRING *asn1_str = gen->d.uniformResourceIdentifier;
list.push_back( string( (char*)ASN1_STRING_data(asn1_str), ASN1_STRING_length(asn1_str) ) );
}
}
else if (distpoint->type==1)//relativename X509NAME
{
STACK_OF(X509_NAME_ENTRY) *sk_relname = distpoint->name.relativename;
for (int k = 0; k < sk_X509_NAME_ENTRY_num(sk_relname); k++)
{
X509_NAME_ENTRY *e = sk_X509_NAME_ENTRY_value(sk_relname, k);
ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
list.push_back( string( (char*)ASN1_STRING_data(d), ASN1_STRING_length(d) ) );
}
}
}
CRL_DIST_POINTS_free(dist_points);
return list;
}
//----------------------------------------------------------------------
void parseCert1(X509* x509)
{
cout <<"--------------------" << endl;
BIO *bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
//PEM_write_bio_X509(bio_out, x509);//STD OUT the PEM
X509_print(bio_out, x509);//STD OUT the details
//X509_print_ex(bio_out, x509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);//STD OUT the details
BIO_free(bio_out);
}
//----------------------------------------------------------------------
void parseCert2(X509* x509)
{
cout <<"--------------------" << endl;
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);
}
//----------------------------------------------------------------------
void parseCert3(X509* x509)
{
cout <<"--------------------" << endl;
//cout << pem(x509) << endl;
cout <<"Thumbprint: " << thumbprint(x509) << endl;
cout <<"Version: " << certversion(x509) << endl;
cout <<"Serial: " << serial(x509) << endl;
cout <<"Issuer: " << issuer_one_line(x509) << endl;
map<string,string> ifields = issuer(x509);
for(map<string, string>::iterator i = ifields.begin(), ix = ifields.end(); i != ix; i++ )
cout << " * " << i->first << " : " << i->second << endl;
cout <<"Subject: " << subject_one_line(x509) << endl;
map<string,string> sfields = subject(x509);
for(map<string, string>::iterator i = sfields.begin(), ix = sfields.end(); i != ix; i++ )
cout << " * " << i->first << " : " << i->second << endl;
cout <<"SignatureAlgorithm: " << signature_algorithm(x509) << endl;
cout <<"PublicKeyType: " << public_key_type(x509) << public_key_ec_curve_name(x509) << endl;
cout <<"PublicKeySize: " << public_key_size(x509) << endl;
cout <<"NotBefore: " << asn1datetime_isodatetime(X509_get_notBefore(x509)) << endl;
cout <<"NotAfter: " << asn1datetime_isodatetime(X509_get_notAfter(x509)) << endl;
cout <<"SubjectAltName(s):" << endl;
vector<string> sans = subject_alt_names(x509);
for(int i=0, ix=sans.size(); i<ix; i++) {
cout << " " << sans[i] << endl;
}
cout <<"CRL URLs:" << endl;
vector<string> crls = crl_urls(x509);
for(int i=0, ix=crls.size(); i<ix; i++) {
cout << " " << crls[i] << endl;
}
cout <<"OCSP URLs:" << endl;
vector<string> urls = ocsp_urls(x509);
for(int i=0, ix=urls.size(); i<ix; i++) {
cout << " " << urls[i] << endl;
}
}
//----------------------------------------------------------------------
int main(int argc, char **argv)
{
OpenSSL_add_all_algorithms();
const char bytes[] = "-----BEGIN CERTIFICATE-----" "\n"
"MIIG4TCCBcmgAwIBAgIQCd0Ux6hVwNaX+SICZIR/jzANBgkqhkiG9w0BAQUFADBm" "\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3" "\n"
"d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j" "\n"
"ZSBDQS0zMB4XDTEzMDUxNDAwMDAwMFoXDTE2MDUxODEyMDAwMFowYDELMAkGA1UE" "\n"
"BhMCQ0ExEDAOBgNVBAgTB0FsYmVydGExEDAOBgNVBAcTB0NhbGdhcnkxGTAXBgNV" "\n"
"BAoTEFNBSVQgUG9seXRlY2huaWMxEjAQBgNVBAMMCSouc2FpdC5jYTCCASIwDQYJ" "\n"
"KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJv2n5mZfX6NV0jZof1WdXGiY5Q/W0yD" "\n"
"T6tUdIYUjgS8GDkeZJYjtwUCMYD2Wo3rF/1ZJ8p9p2WBP1F3CVvjgO+VeA7tLJsf" "\n"
"uAr+S8GE1q5tGO9+lPFkBAZkU38FNfBUblvz1imWb6ORXMc++HjUlrUB0nr2Ae8T" "\n"
"1I3K0XGArHJyW5utJ5Xm8dNEYCcs6EAXchiViVtcZ2xIlSQMs+AqhqnZXo2Tt1H+" "\n"
"f/tQhQJeMTkZ2kklUcnQ1izdTigMgkOvNzW4Oyd9Z0sBbxzUpneeH3nUB5bEv3MG" "\n"
"4JJx7cAVPE4rqjVbtm3v0QbCL/X0ZncJiKl7heKWO+j3DnDZS/oliIkCAwEAAaOC" "\n"
"A48wggOLMB8GA1UdIwQYMBaAFFDqc4nbKfsQj57lASDU3nmZSIP3MB0GA1UdDgQW" "\n"
"BBTk00KEbrhrTuVWBY2cPzTJd1c1BTBkBgNVHREEXTBbggkqLnNhaXQuY2GCB3Nh" "\n"
"aXQuY2GCCmNwLnNhaXQuY2GCDmNwLXVhdC5zYWl0LmNhghd1YXQtaW50ZWdyYXRp" "\n"
"b24uc2FpdC5jYYIQdWF0LWFwYXMuc2FpdC5jYTAOBgNVHQ8BAf8EBAMCBaAwHQYD" "\n"
"VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGEGA1UdHwRaMFgwKqAooCaGJGh0" "\n"
"dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9jYTMtZzIxLmNybDAqoCigJoYkaHR0cDov" "\n"
"L2NybDQuZGlnaWNlcnQuY29tL2NhMy1nMjEuY3JsMIIBxAYDVR0gBIIBuzCCAbcw" "\n"
"ggGzBglghkgBhv1sAQEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2lj" "\n"
"ZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFW" "\n"
"HoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBm" "\n"
"AGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0" "\n"
"AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAv" "\n"
"AEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0" "\n"
"AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAg" "\n"
"AGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBw" "\n"
"AG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBu" "\n"
"AGMAZQAuMHsGCCsGAQUFBwEBBG8wbTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au" "\n"
"ZGlnaWNlcnQuY29tMEUGCCsGAQUFBzAChjlodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy" "\n"
"dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlQ0EtMy5jcnQwDAYDVR0TAQH/BAIw" "\n"
"ADANBgkqhkiG9w0BAQUFAAOCAQEAcl2YI0iMOwx2FOjfoA8ioCtGc5eag8Prawz4" "\n"
"FFs9pMFZfD/K8QvPycMSkw7kPtVjmuQWxNtRAvCSIhr/urqNLBO5Omerx8aZYCOz" "\n"
"nsmZpymxMt56DBw+KZrWIodsZx5QjVngbE/qIDLmsYgtKczhTCtgEM1h/IHlO3Ho" "\n"
"7IXd2Rr4CqeMoM2v+MTV2FYVEYUHJp0EBU/AMuBjPf6YT/WXMNq6fn+WJpxcqwJJ" "\n"
"KtBh7c2vRTklahbh1FaiJ0aFJkDH4tasbD69JQ8R2V5OSuGH6Q7EGlpNl+unqtUy" "\n"
"KsAL86HvgzF5D51C9TmFXEtXTlPKnjoqn1TC4Rqpqvh+FHWPJQ==" "\n"
"-----END CERTIFICATE-----";
BIO *bio_mem = BIO_new(BIO_s_mem());
BIO_puts(bio_mem, bytes);
X509 * x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
parseCert1(x509);
parseCert2(x509);
parseCert3(x509);
BIO_free(bio_mem);
X509_free(x509);
}
//----------------------------------------------------------------------
Partial Output
Version: 3
Serial: 09dd14c7a855c0d697f9220264847f8f
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance CA-3
Valid From: May 14 00:00:00 2013 GMT
Valid Until: May 18 12:00:00 2016 GMT
Subject: C=CA, ST=Alberta, L=Calgary, O=SAIT Polytechnic, CN=*.sait.ca
Public-Key: (2048 bit)
Modulus:
00:9b:f6:9f:99:99:7d:7e:8d:57:48:d9:a1:fd:56:
75:71:a2:63:94:3f:5b:4c:83:4f:ab:54:74:86:14:
8e:04:bc:18:39:1e:64:96:23:b7:05:02:31:80:f6:
5a:8d:eb:17:fd:59:27:ca:7d:a7:65:81:3f:51:77:
09:5b:e3:80:ef:95:78:0e:ed:2c:9b:1f:b8:0a:fe:
4b:c1:84:d6:ae:6d:18:ef:7e:94:f1:64:04:06:64:
53:7f:05:35:f0:54:6e:5b:f3:d6:29:96:6f:a3:91:
5c:c7:3e:f8:78:d4:96:b5:01:d2:7a:f6:01:ef:13:
d4:8d:ca:d1:71:80:ac:72:72:5b:9b:ad:27:95:e6:
f1:d3:44:60:27:2c:e8:40:17:72:18:95:89:5b:5c:
67:6c:48:95:24:0c:b3:e0:2a:86:a9:d9:5e:8d:93:
b7:51:fe:7f:fb:50:85:02:5e:31:39:19:da:49:25:
51:c9:d0:d6:2c:dd:4e:28:0c:82:43:af:37:35:b8:
3b:27:7d:67:4b:01:6f:1c:d4:a6:77:9e:1f:79:d4:
07:96:c4:bf:73:06:e0:92:71:ed:c0:15:3c:4e:2b:
aa:35:5b:b6:6d:ef:d1:06:c2:2f:f5:f4:66:77:09:
88:a9:7b:85:e2:96:3b:e8:f7:0e:70:d9:4b:fa:25:
88:89
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:50:EA:73:89:DB:29:FB:10:8F:9E:E5:01:20:D4:DE:79:99:48:83:F7
X509v3 Subject Key Identifier:
E4:D3:42:84:6E:B8:6B:4E:E5:56:05:8D:9C:3F:34:C9:77:57:35:05
X509v3 Subject Alternative Name:
DNS:*.sait.ca, DNS:sait.ca, DNS:cp.sait.ca, DNS:cp-uat.sait.ca, DNS:uat-integration.sait.ca, DNS:uat-apas.sait.ca
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl3.digicert.com/ca3-g21.crl
Full Name:
URI:http://crl4.digicert.com/ca3-g21.crl
X509v3 Certificate Policies:
Policy: 2.16.840.1.114412.1.1
CPS: http://www.digicert.com/ssl-cps-repository.htm
User Notice:
Explicit Text:
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertHighAssuranceCA-3.crt
X509v3 Basic Constraints: critical
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
72:5d:98:23:48:8c:3b:0c:76:14:e8:df:a0:0f:22:a0:2b:46:
73:97:9a:83:c3:eb:6b:0c:f8:14:5b:3d:a4:c1:59:7c:3f:ca:
f1:0b:cf:c9:c3:12:93:0e:e4:3e:d5:63:9a:e4:16:c4:db:51:
02:f0:92:22:1a:ff:ba:ba:8d:2c:13:b9:3a:67:ab:c7:c6:99:
60:23:b3:9e:c9:99:a7:29:b1:32:de:7a:0c:1c:3e:29:9a:d6:
22:87:6c:67:1e:50:8d:59:e0:6c:4f:ea:20:32:e6:b1:88:2d:
29:cc:e1:4c:2b:60:10:cd:61:fc:81:e5:3b:71:e8:ec:85:dd:
d9:1a:f8:0a:a7:8c:a0:cd:af:f8:c4:d5:d8:56:15:11:85:07:
26:9d:04:05:4f:c0:32:e0:63:3d:fe:98:4f:f5:97:30:da:ba:
7e:7f:96:26:9c:5c:ab:02:49:2a:d0:61:ed:cd:af:45:39:25:
6a:16:e1:d4:56:a2:27:46:85:26:40:c7:e2:d6:ac:6c:3e:bd:
25:0f:11:d9:5e:4e:4a:e1:87:e9:0e:c4:1a:5a:4d:97:eb:a7:
aa:d5:32:2a:c0:0b:f3:a1:ef:83:31:79:0f:9d:42:f5:39:85:
5c:4b:57:4e:53:ca:9e:3a:2a:9f:54:c2:e1:1a:a9:aa:f8:7e:
14:75:8f:25
上一篇: NMEA报文解析程序(c语言)-解析报文