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/
        ./config
        make
        sudo make install
    #3. 刷新动态链接库
        默认配置下生成的libcrypto和libssl会安装在/usr/local/lib目录,并覆盖系统openssl中这两个库的软链接。
        刷新库的话有可能造成部分系统应用无法使用,命令如下:
        sudo ldconfig
        如果不刷,可以采用以下方法替代,将环境变量临时修改到安装包的目录,此时命令行可以照常使用:
        export LD_LIBRARY_PATH=$(pwd)

GmSSL的命令行操作和OpenSSL大同小异,这里演示用SM2标准生成公私钥对,并进行加解密运算。

    #1. 生成密钥
        // 这里输出了私钥为dkey.pem
        gmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:sm2p256v1 -pkeyopt ec_param_enc:named_curve -out dkey.pem
        // 这里用私钥产生公钥ekey.pem
        gmssl 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:sm3

2.用GmSSL编程

这里实验了部分API的功能,由于时间有限而网络资料偏少,只测试通过了以SM2标准生成公私钥文件的功能。公钥加密功能出现运行错误,未来得及排查修改。测试代码如下,只保留了有用部分:

     #include 
     #include 
     #include 
     #include 
     #include 
     #include 
     #include 

     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

你可能感兴趣的:(安全开发)