GmSSL初次探索
GmSSL初次探索
1.安裝及命令行
GmSSL是一個支持國家加密算法標準GM/T的開源加密套件,由于它是OpenSSL的分支,因此保留了OpenSSL1.1.0的所有功能和API級別的兼容性。遺留項目如Apache的WEB Server可以通過很小的改動并重新編譯就適配到GmSSL中。自2014年發布第一版以來,GmSSL被開源中國社區選為6個推薦的加密項目,同時也是2015中國linux軟件獎得主。
GmSSL的安裝步驟可以按照以下過程來:
#0. 安裝環境Ubuntu 18.04 LTS#1. 下載GmSSL源碼Github鏈接:https://github.com/guanzhi/GmSSL#2. 編譯安裝在編譯前可選擇性地修改源碼crypto/ec/ec_pmeth.c,第66行改為dctx->ec_encrypt_param = NID_sm3;這里假設不做修改,以此配置、編譯、安裝cd GmSSL/./configmakesudo make install#3. 刷新動態鏈接庫默認配置下生成的libcrypto和libssl會安裝在/usr/local/lib目錄,并覆蓋系統openssl中這兩個庫的軟鏈接。刷新庫的話有可能造成部分系統應用無法使用,命令如下:sudo ldconfig如果不刷,可以采用以下方法替代,將環境變量臨時修改到安裝包的目錄,此時命令行可以照常使用:export LD_LIBRARY_PATH=$(pwd)GmSSL的命令行操作和OpenSSL大同小異,這里演示用SM2標準生成公私鑰對,并進行加解密運算。
#1. 生成密鑰// 這里輸出了私鑰為dkey.pemgmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:sm2p256v1 -pkeyopt ec_param_enc:named_curve -out dkey.pem// 這里用私鑰產生公鑰ekey.pemgmssl pkey -pubout -in dkey.pem -out ekey.pem#2. 用公鑰加密,私鑰解密// 加密"Top Secret"這句話并輸出到cipher.sm2文件中// 最后的選項在未改源碼情況下必須要加的echo "Top Secret" | gmssl pkeyutl -encrypt -pkeyopt ec_scheme:sm2 -pubin -inkey ekey.pem -out cipher.sm2 -pkeyopt ec_encrypt_param:sm3// 同理,在添加該選項的情況下解密,結果會在終端輸出gmssl pkeyutl -decrypt -pkeyopt ec_scheme:sm2 -inkey dkey.pem -in cipher.sm2 -pkeyopt ec_encrypt_param:sm32.用GmSSL編程
這里實驗了部分API的功能,由于時間有限而網絡資料偏少,只測試通過了以SM2標準生成公私鑰文件的功能。公鑰加密功能出現運行錯誤,未來得及排查修改。測試代碼如下,只保留了有用部分:
#include <openssl/conf.h>#include <openssl/evp.h>#include <openssl/err.h>#include <openssl/obj_mac.h>#include <openssl/ec.h>#include <openssl/pem.h>#include <stdio.h>int main(int arc, char *argv[]){/* Load the human readable error strings for libcrypto */ERR_load_crypto_strings();/* Load all digest and cipher algorithms */OpenSSL_add_all_algorithms(); /* Load config file, and other important initialisation */OPENSSL_config(NULL);/* ... Do some crypto stuff here ... *//* EVP函數 返回1表示成功;返回0表示錯誤;-1表示內部過程出錯 *//* 創建用于生成參數的上下文 */EVP_PKEY_CTX *pctx = NULL;if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) goto err;if(EVP_PKEY_paramgen_init(pctx)!=1) goto err;/* 設置使用的橢圓曲線類型編號及加密算法 */if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2p256v1)) goto err;if(!EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE)) goto err;/* 生成上下文密鑰 */EVP_PKEY *key = NULL;if(!EVP_PKEY_keygen_init(pctx)) goto err;if(!EVP_PKEY_keygen(pctx, &key)) goto err;/* 生成PEM格式文件密鑰 */FILE *fp1 = fopen("1Priv.pem","w");FILE *fp2 = fopen("2Pubk.pem","w");/* 輸出私鑰文件 */if(!PEM_write_ECPrivateKey(fp1, EVP_PKEY_get1_EC_KEY(key), NULL, NULL, 0, NULL, NULL)) goto err;/* 輸出公鑰文件 */if(!PEM_write_EC_PUBKEY(fp2, EVP_PKEY_get1_EC_KEY(key))) goto err;fclose(fp1);fclose(fp2);printf("ALL procedures succeed!\n");/* 在這里處理異常,方式為輸出錯誤信息 */err:{printf("Exception occured!\n");ERR_print_errors_fp(stderr); //將錯誤string輸出標準錯誤}/* Clean up *//* Removes all digests and ciphers */EVP_cleanup(); /* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */CRYPTO_cleanup_all_ex_data(); /* Remove error strings */ERR_free_strings();return 0;}編譯并執行gcc -o 1elf main.c -lcrypto && ./1elf,會生成兩個PEM格式密鑰文件,可以用命令行代入它們加解密運算發現文件可用。
這里需要說的是代碼中主要調用EVP部分的API。EVP(Envelop)函數是庫中提供的高級API,其大部分API都和命令行參數有一一對應關系。有時要編寫更細粒度的操作代碼,則可以用一些低級API,如BIO函數及各個密碼算法的對應API。
3.參考文獻
當然,最重要的還是留下參考文獻的鏈接,我認為有用的參考文檔如下:
-
官網EVP庫介紹(主要是對稱加密函數和模板)http://gmssl.org/docs/evp-api.html
-
Openssl1.1.0官方Manual的crypto部分https://www.openssl.org/docs/man1.1.0/crypto/
-
項目Github倉庫的Demos部分(公鑰加密部分不多)https://github.com/guanzhi/GmSSL/tree/master/demos
總結
- 上一篇: 【OS学习笔记】二十七 保护模式八:任务
- 下一篇: 枚举类型创建实例