Openssl EVP 說明四 (函數Sign ...) 分享

openssl之EVP系列之10---EVP_Sign系列函數介紹

---根據openssl doc\crypto\EVP_SignInit.pod翻譯
(作者:DragonKing, Mail: [email protected] ,發佈於:http://openssl.126.com之openssl專業論壇,版本:openssl-0.9.7)

EVP_Sign系列函數使用的基礎結構跟信息摘要算法使用的基礎結構是一樣的,而且,其前面的兩個操作步驟初始化和數據操作(信息摘要)也跟信息摘要算法是一樣的,唯一不一樣的是最後一步操作,本系列函數做了簽名的工作,而信息摘要系列函數當然就只是簡單的處理完摘要信息了事了。其實這是很容易理解的事情,因爲簽名算法就是在信息摘要之後用私鑰進行簽名的過程。本系列函數定義的如下(openssl\evp.h):
     int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
     int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
     int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);

     void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);

     int EVP_PKEY_size(EVP_PKEY *pkey);

【EVP_SignInit_ex】

該函數是一個宏定義函數,其實際定義如下:
#define EVP_SignInit_ex(a,b,c)  EVP_DigestInit_ex(a,b,c)
可見,該函數跟前面敘述的EVP_DigestInit_ex的功能和使用方法是一樣的,都是使用ENGINE參數impl所代表的實現函數功能來設置結構ctx。在調用本函數前,參數ctx一定要經過EVP_MD_CTX_init函數初始化。詳細使用方法參看前面的文章介紹。成功返回1,失敗返回0。

【EVP_SignUpdate】
該函數也是一個宏定義函數,其實際定義如下:
#define EVP_SignUpdate(a,b,c)  EVP_DigestUpdate(a,b,c)
該函數使用方法和功能也跟前面介紹的EVP_DigestUpdate函數一樣,將一個cnt字節的數據經過信息摘要運算存儲到結構ctx中,該函數可以在一個相同的ctx中調用多次來實現對更多數據的信息摘要工作。成功返回1,失敗返回0。

【EVP_SignFinal】
該函數跟前面兩個函數不同,這是簽名系列函數跟信息摘要函數開始不同的地方,其實,該函數是將簽名操作的信息摘要結構ctx拷貝一份,然後調用EVP_DigestFinal_ex完成信息摘要工作,然後開始對摘要信息用私鑰pkey進行簽名,並將簽名信息保存在參數sig裏面。如果參數s不爲NULL,那麼就會將簽名信息數據的長度(單位字節)保存在該參數中,通常寫入的數據是EVP_PKEY_size(key)。
因爲操作的時候是拷貝了一份ctx,所以,原來的ctx結構還可以繼續使用EVP_SignUpdate和EVP_SignFinal函數來完成更多信息的簽名工作。不過,最後一定要使用EVP_MD_CTX_cleanup函數清除和釋放ctx結構,否則就會造成內存泄漏。
此外,當使用DSA私鑰簽名的時候,一定要對產生的隨機數進行種子播種工作(seeded),否則操作就會失敗。RSA算法則不一定需要這樣做。至於使用的簽名算法跟摘要算法的關係,在EVP_Digest系列中已經有詳細說明,這裏不再重複。
本函數操作成功返回1,否則返回0。

【EVP_SignInit】
本函數也是一個宏定義函數,其定義如下:
#define EVP_SignInit(a,b)  EVP_DigestInit(a,b)
所以其功能和用法跟前面介紹的EVP_DigestInit函數完全一樣,使用缺省實現的算法初始化算法結構ctx。

【EVP_PKEY_size】
本函數返回一個簽名信息的最大長度(單位字節)。實際簽名信息的長度則由上述的函數EVP_SignFinal返回,有可能比這小。
上述所有函數發生錯誤,可以使用ERR_get_error函數獲得錯誤碼。




openssl之EVP系列之11---EVP_Verify系列函數介紹

---根據openssl doc\crypto\EVP_VerifyInit.pod翻譯和自己的理解寫成
(作者:DragonKing, Mail: [email protected] ,發佈於:http://openssl.126.com之openssl專業論壇,版本:openssl-0.9.7)

跟EVP_Sign系列函數一樣,EVP_Verify系列函數的前兩步(初始化和信息摘要處理)跟信息摘要算法是一樣的,因爲簽名驗證的過程就是先對信息進行信息摘要,然後再將發來的摘要信息解密後進行比較的過程,其定義如下(openssl\evp.h):
     int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
     int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
     int EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf, unsigned int siglen,EVP_PKEY *pkey);

     int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);

【EVP_VerifyInit_ex】

該函數是一個宏定義函數,其實際定義如下:
#define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)
所以,其功能和使用方法跟前面介紹的EVP_DigestInit_ex函數是一樣的。該函數使用參數impl所提供的算法庫對驗證結構ctx進行設置。在調用本函數之前,參數ctx必須經過調用EVP_MD_CTX_init進行初始化。成功返回1,失敗返回0。

【EVP_VerifyUpdate】
該函數也是一個宏定義函數,其實際定義如下:
#define EVP_VerifyUpdate(a,b,c)  EVP_DigestUpdate(a,b,c)
所以,其功能和使用方法跟前面介紹的EVP_DigestUpdate函數是相同的。該函數將參數d中的cnt字節數據經過信息摘要計算後保存到ctx中,該函數可以進行多次調用,以處理更多的數據。成功調用返回1,失敗返回0。

【EVP_VerifyFinal】
該函數使用公鑰pkey和ctx結構裏面的信息驗證sigbuf裏面的數據的簽名。事實上,該函數先調用EVP_MD_CTX_copy_ex函數將原來的ctx拷貝一份,然後調用EVP_DigestFinal_ex函數完成拷貝的ctx的信息摘要計算,最後才使用公鑰進行簽名的驗證工作。
因爲該函數實際上處理的是原來ctx函數的一個拷貝,所以原來的ctx結構還可以調用EVP_VerifyUpdate和EVP_VerifyFinal函數進行更多的數據處理和簽名驗證工作。
在使用完之後,ctx必須使用EVP_MD_CTX_cleanup函數釋放內存,否則就會導致內存泄漏。
此外,至於信息摘要算法和簽名算法的關聯的關係,請參照信息摘要算法部分的說明。
該函數調用成功返回1,失敗則返回0或-1。

【EVP_VerifyInit】
該函數使用缺省的實現算法對ctx結構進行初始化。也是一個宏定義函數,其定義如下:
#define EVP_VerifyInit(a,b)  EVP_DigestInit(a,b)
所以跟EVP_DigestInit函數功能和用法是一樣的。



penssl之EVP系列之12---EVP_Seal系列函數介紹

---根據openssl doc\crypto\EVP_SealInit.pod翻譯和自己的理解寫成
(作者:DragonKing, Mail: [email protected] ,發佈於:http://openssl.126.com之openssl專業論壇,版本:openssl-0.9.7)

改系列函數是相當於完成一個電子信封的功能,它產生一個隨機密鑰,然後使用一個公鑰對改密鑰進行封裝,數據可以使用隨機密鑰進行加密。
信封加密在進行大量數據傳輸的時候是必須經常要用到的,因爲公開密鑰算法的加解密速度很慢,但對稱算法就快多了。所以一般用公開密鑰算法進行加密密鑰的傳輸,而真正進行數據加密則使用對稱加密算法。
其定義的函數如下(openssl\evp.h):
     int EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek,
                    int *ekl, unsigned char *iv,EVP_PKEY **pubk, int npubk);
     int EVP_SealUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
             int *outl, unsigned char *in, int inl);
     int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
             int *outl);

【EVP_SealInit】

該函數初始化一個加密算法結構EVP_CIPHER_CTX,採用了指定的加密算法,使用一個隨機密鑰和初始化向量IV。事實上,該函數調用EVP_EncryptInit_ex函數兩次完成了ctx結構的初始化工作。參數type是算法類型,跟簽名介紹過的是一樣的,爲EVP_des_cbc類型的函數。隨機私鑰被一個或多個公鑰加密,這就允許祕鑰被公鑰相應的私鑰解密。參數ek是一個緩存序列,可以存放多個被公鑰加密後的密鑰的信息,所以每個緩存空間都應該足夠大,比如ek[i]的緩存空間就必須爲EVP_PKEY_size(pubk[i])那麼大。每個被加密密鑰的長度保存在數字ekl中。參數pubk是一個公鑰陳列,可以包含多個公鑰。函數成功執行返回npubk,失敗返回0。
因爲該函數的密鑰是隨機產生的,隨意在調用該函數之前,必須對隨機數播種(seeded)。
使用的公鑰必須是RSA,因爲在openssl裏面這是唯一支持密鑰傳輸的公鑰算法。
跟EVP_EncryptInit函數一樣,本函數也可以分爲兩次調用,第一次調用的時候要將參數npubk設爲0,第二調用的時候就應該將參數type設爲NULL。

【EVP_SealUpdate】
該函數是一個宏定義函數,其實際定義如下:
#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e)
由此可見,其完成的功能和使用方法跟EVP_EncryptUpdate函數是一樣的。細節參看前面介紹的文章。成功執行返回1,否則返回0。

【EVP_SealFinal】
該函數簡單調用了EVP_EncryptFinal_ex完成其功能,所以其完成的功能和使用參數也跟EVP_EncryptFinal_ex函數一樣,細節請參考相關文章。唯一不一樣的是,該函數還調用EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL)函數對ctx結構再次進行了初始化。成功返回1,否則返回0。




penssl之EVP系列之13---EVP_Open系列函數介紹

---根據openssl doc\crypto\EVP_OpenInit.pod翻譯和自己的理解寫成
(作者:DragonKing, Mail: [email protected] ,發佈於:http://openssl.126.com之openssl專業論壇,版本:openssl-0.9.7)

本系列函數相對於EVP_Seal系列函數,是進行信封加密的。它將公鑰加密了的密鑰加密出來,然後進行數據的解密。其定義的函數如下(openssl\evp.h):
     int EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
                    int ekl,unsigned char *iv,EVP_PKEY *priv);
     int EVP_OpenUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
             int *outl, unsigned char *in, int inl);
     int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
             int *outl);

【EVP_OpenInit】

該函數初始化一個用來加密數據的ctx結構。它使用參數priv的私鑰解密參數ek裏面長度爲ekl字節的加密密鑰。參數iv是初始化向量。如果參數type設定的加密算法長度是可變的,那麼密鑰長度就會被設置爲解密得到的密鑰的長度;如果加密算法長度是固定的,那麼得到的解密密鑰的長度就必須跟固定算法長度相同纔行。成功執行返回密鑰的長度,否則返回0。
跟函數EVP_DecryptInit一樣,該函數也可以分成多次調用,首次調用應該將參數priv設置爲NULL,再次調用的時候應該將type設置爲NULL。

【EVP_OpenUpdate】
該函數是一個宏定義函數,其實際定義如下:
#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e)
所以,其功能和使用方法跟前面介紹過的EVP_DecryptUpdate相同,請參考相應的文章。成功執行返回1,否則返回0。

【EVP_OpenFinal】
事實上,該函數調用EVP_DecryptFinal_ex完成了其功能,所以其使用方法跟功能跟函數EVP_DecryptFinal_ex是一樣的,參考該函數說明就可以。唯一不同的是,本函數還調用EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL)再次進行了初始化工作。成功執行返回1,否則返回0。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章