1. 程式人生 > >藉助openssl將資料轉換為ASN1 der格式

藉助openssl將資料轉換為ASN1 der格式

本文是參照別的文章,再根據自己實踐後整理的,若有不當之處,還請批評指正!

使用openssl將C結構體轉換為ASN1 Der格式時,首先需要包含如下幾個標頭檔案:

#include <openssl/asn1.h>

#include <openssl/asn1t.h>

#include <openssl/ossl_typ.h>

然後,按如下三個步驟進行操作,通過示例程式進行介紹,假如想將結構體ECCrefPublicKey 進行轉換,該結構體定義如下:

typedef struct ECCrefPublicKey_st

{

     unsigned char x[ECCref_MAX_LEN]; 

     unsigned char y[ECCref_MAX_LEN]; 

} ECCrefPublicKey;

 

第一步:在標頭檔案中定義如下結構體,並進行宣告

//結構體定義(將其理解為ASN1格式下與ECCrefPublicKey相對應的結構,我們的目的就是將普通二進位制格式下的ECCrefPublicKey轉換為ASN1標準對應下的格式,有點類似於我們數學中學的一一對映的意思

)

Typedef struct  ASN_ECCPUBLICKEY_st

{

       ASN1_OCTET_STRING *X;

       ASN1_OCTET_STRING *Y;

} ASN_ECCPUBLICKEY;

 

//隨後使用如下語句進行宣告

DECLARE_ASN1_FUNCTIONS(ASN_ECCPUBLICKEY)

ASN_ECCPUBLICKEY 中  X Y分量對應於ECCrefPublicKey中兩個分量,其型別對應於ASN1 下的型別,ASN1下的資料型別也有很多,根據實際要求進行定義。

 

第二步: 在實現檔案.C檔案中宣告一些變數和結構體:

ASN1_SEQUENCE(ASN_ECCPUBLICKEY) = {

      ASN1_SIMPLE(ASN_ECCPUBLICKEY, X, ASN1_OCTET_STRING),

       ASN1_SIMPLE(ASN_ECCPUBLICKEY, Y, ASN1_OCTET_STRING),

 } ASN1_SEQUENCE_END(ASN_ECCPUBLICKEY);

其中每一項,對應於第一步中定義的ASN1結構體變數。

第三步:在實現檔案.C檔案中呼叫實現巨集

 IMPLEMENT_ASN1_FUNCTIONS(ASN_ECCPUBLICKEY)

第三步就上面一個語句,一般放在第二步的後面。此時,ASN1轉換準備工作就執行完畢了,通過上面三個步驟,openssl就為其定義瞭如下幾個函式:

d2i_ ASN_ECCPUBLICKEY( )i2d_ASN_ECCPUBLICKEY()、ASN_ECCPUBLICKEY_new( )ASN_ECCPUBLICKEY_free()

 

至此,就可以依據這四個函式來對C結構體進行轉換了,藉助於上面四個函式定義如下函式:

 

 

int i2d_ECC_PublicKey(const ECCrefPublicKey *cipher, unsigned char **out)

{

       ASN_ECCPUBLICKEY *ec = NULL;

       int             len = 0;

 

       ec = ASN_ECCPUBLICKEY_new();

       if (ec == NULL) {

              return 0;

       }

 

       do {

              if (!ASN1_OCTET_STRING_set(ec->X, cipher->x, 32))

                     break;

 

              if (!ASN1_OCTET_STRING_set(ec->Y, cipher->y, 32))

                     break;

 

              /* i2d */

              len = i2d_ASN_ECCPUBLICKEY(ec, out);

 

       } while (0);

 

       ASN_ECCPUBLICKEY_free(ec);

 

       return len; //返回值時編碼為ASN1後的 位元組大小

}

 

int d2i_ECC_PublicKey(ECCrefPublicKey *ins, const unsigned char **ppin, long pplen)

{

       ASN_ECCPUBLICKEY *ec = NULL;

 

       /* DECODE */

       ec = d2i_ASN_ECCPUBLICKEY(NULL, ppin, pplen);

       if (ec == NULL) {

              return 0;

       }

 

       /* check version ? */

       do {

              if (ec->X->length <= 0 || ec->Y->length <= 0)

                     break;

              memcpy(ins->x, ec->X->data, ec->X->length);

             memcpy(ins->y, ec->Y->data, ec->Y->length);

             ASN_ECCPUBLICKEY_free(ec);

              return 1;

 

       } while(0);

 

       ASN_ECCPUBLICKEY_free(ec);

       return 1;

}

 

 

此後,我們直接呼叫i2d_ECC_PublicKey d2i_ECC_PublicKey 兩個函式,就可以實現C結構體到 Der格式之間的相互轉換。()

 

補充:C結構體中各成員變數都是二進位制資料,我們可以按 十六進位制 方式列印顯示,ASN1 Der格式是在C結構體資料本身基礎上,添加了一些標記的結果。因此ASN1 Der編碼的資料 C 結構體本身資料 是要大幾個位元組的。