1. 程式人生 > >openssl 學習之證書中提取N 和 E

openssl 學習之證書中提取N 和 E

通常數字證書包含很多資訊,其中N和E值即我們稱為的公鑰。如何從PEM 或者DER格式的證書中提出證書呢?下面給出程式碼實現從PEM和DER編碼的證書中提出N、E。

#include <openssl/evp.h>
#include <openssl/x509.h>
#include <stdio.h>
#include <stdlib.h>
void PrintHex(unsigned char *str, unsigned int len)
{
    int i = 0;
    for(i =0;i< len; i++)
    {
        if(i%4 == 0)
	{
	   printf("0x");
	}
        printf("%02x",str[i]);
	if(i%4 == 3)
        {
           printf(" ");
        }
        if(i%16 == 15)
        {
	    printf("\n");
        }
    }
    printf("\n");
}
void GetPukfromPEM()
{
    X509 *x;
    BIO	*b;
    EVP_PKEY *k;
    RSA *rsa;
    unsigned char n[300] ={0x0};
    unsigned char e[300] ={0x0};
    unsigned int len;
    /*www.google.com1為PEM格式的數字證書,從firefox中匯出 */ 	
    b=BIO_new_file("www.google.com1","r");
    x=PEM_read_bio_X509(b,NULL,NULL,NULL);
    k=X509_get_pubkey(x);
    rsa=EVP_PKEY_get1_RSA(k);
    if(rsa->n != NULL)
    {
        BN_bn2bin(rsa->n, n);
        len= BN_num_bytes(rsa->n);
        printf("N:\n");
        PrintHex(n,len);
    }
    else
    {
        printf("PEM error \n");
    }
    if(rsa->e != NULL)
    {
        BN_bn2bin(rsa->e, e);
        len= BN_num_bytes(rsa->e);  
       	printf("E:\n");
        PrintHex(e,len);
    }
    else
    {
        printf("PEM error \n");
    }
    BIO_free(b);
    X509_free(x);
}
void GetPukfromDER()
{
    X509 *x;
    FILE *fp;
    unsigned char	buf[5000],*p;
    int	ret;
    BIO	*b;
    EVP_PKEY *k;
    RSA *rsa;
    unsigned char n[300] ={0x0};
    unsigned char e[300] ={0x0};
    unsigned int len;
	/* www.google.com2為DER編碼的數字證書 ,從firefox中匯出
	*/
    fp=fopen("www.google.com2","rb");
    if(!fp) return ;
    len=fread(buf,1,5000,fp);
    fclose(fp);
    p=buf;
    x=X509_new();
    d2i_X509(&x,(const unsigned char **)&p,len);
    k=X509_get_pubkey(x);
    rsa=EVP_PKEY_get1_RSA(k);
    if(rsa->n != NULL)
    {
        BN_bn2bin(rsa->n, n);
        len= BN_num_bytes(rsa->n);
	printf("N:\n");
	PrintHex(n,len);
    }
    else
    {
        printf("DER error \n");
    }
    if(rsa->e != NULL)
    {
        BN_bn2bin(rsa->e, e);
        len= BN_num_bytes(rsa->e);
        printf("E:\n");
        PrintHex(e,len);
    }
    else
    {
        printf("DER error \n");
    }
    BIO_free(b);
    X509_free(x);   
}
int main()
{
	GetPukfromPEM();
	GetPukfromDER();
	return 0;
}

程式執行結果如下:

N:
0xb073f0f2 0x04eec2a2 0x46ca342a 0xaabb6023 
0xd111761f 0x1f3ad065 0x834e9a45 0xa8437085 
0x76f01f87 0x00021f6e 0x3b1717c4 0xb5e91946 
0xa292258d 0x622ab463 0x301fb985 0xf835e116 
0x5a7649cc 0x50485339 0x5989d684 0x02fb9aec 
0x1bc751d5 0x769590d4 0x3a2ab8a6 0xde024d06 
0xfbcdeda5 0x46415f55 0x74e5ec7e 0x40dc509c 
0xb5e4355d 0x1e6820f8 0xe9dea36a 0x28bf41d2 
0xa1b3e225 0x8d0c1bca 0x3d930c18 0xaedfc5bc 
0xfdbc82ba 0x6800d716 0x32719f65 0xb511da68 
0x59d0a657 0x641bc9fe 0x98e5f5a5 0x65eae1db 
0xeef4b39d 0xb38eea87 0xae16d21e 0xa07c7c69 
0x3f291685 0x0153a76c 0xf160abdd 0xa2fc2547 
0xd432d112 0xddf74812 0xe0fc9ca2 0x7798e989 
0x99b8f838 0xf18c06c2 0x7a23366d 0x9b9dcd30 
0xc8c73417 0x1ebb7d42 0xc8abe715 0x16f673b5 
 
E:
0x010001
N:
0xb073f0f2 0x04eec2a2 0x46ca342a 0xaabb6023 
0xd111761f 0x1f3ad065 0x834e9a45 0xa8437085 
0x76f01f87 0x00021f6e 0x3b1717c4 0xb5e91946 
0xa292258d 0x622ab463 0x301fb985 0xf835e116 
0x5a7649cc 0x50485339 0x5989d684 0x02fb9aec 
0x1bc751d5 0x769590d4 0x3a2ab8a6 0xde024d06 
0xfbcdeda5 0x46415f55 0x74e5ec7e 0x40dc509c 
0xb5e4355d 0x1e6820f8 0xe9dea36a 0x28bf41d2 
0xa1b3e225 0x8d0c1bca 0x3d930c18 0xaedfc5bc 
0xfdbc82ba 0x6800d716 0x32719f65 0xb511da68 
0x59d0a657 0x641bc9fe 0x98e5f5a5 0x65eae1db 
0xeef4b39d 0xb38eea87 0xae16d21e 0xa07c7c69 
0x3f291685 0x0153a76c 0xf160abdd 0xa2fc2547 
0xd432d112 0xddf74812 0xe0fc9ca2 0x7798e989 
0x99b8f838 0xf18c06c2 0x7a23366d 0x9b9dcd30 
0xc8c73417 0x1ebb7d42 0xc8abe715 0x16f673b5 
 
E:
0x010001