网络对抗期末(二~四)

加密实验室

实验二~四:密钥加密实验室、单向哈希函数实验室、公钥加密和PKI实验室

密钥加密实验室:探索秘密密钥加密及其使用OpenSSL的应用程序。

单向哈希函数实验室:探索使用OpenSSL的单向散列函数及其应用程序。

公钥加密和PKI实验室:使用OpenSSL探索公钥密码学,数字签名,证书和PKI。

1 基础理论

1.1 GmSSL简介

GmSSL是一个开源密码工具包,提供对中国国家密码算法和协议的第一级支持,这些算法和协议已在GM/T系列标准中规定。作为OpenSSL项目的一个分支,GmSSL提供了与OpenSSL的API级兼容,并且保持了所有功能。现有的项目,如Apache Web服务器,可以很容易地通过少量修改和简单的重新构建移植到GmSSL上。自2014年底首次发布以来,GmSSL已被Open Source China选为六个推荐的加密项目之一,也被评为2015年中国Linux软件奖的获胜者。

GmSSL具有以下特点:

1. 支持国家密码算法和协议。GmSSL支持国家密码标准中规定的算法和协议,包括SM2、SM3、SM4等算法,这些算法在中国的应用范围广泛,并得到了政府的大力支持。

2. 与OpenSSL兼容。GmSSL与OpenSSL具有API级别兼容性,这意味着使用GmSSL的开发人员可以在不太改变代码的情况下,将现有的OpenSSL项目移植到GmSSL上。

3. 维护所有功能。GmSSL保持了OpenSSL的所有功能,包括对称加密、非对称加密、哈希、数字签名等方面的支持。

4. 易于使用。GmSSL提供了易于使用的接口和文档,使得开发人员可以快速地学习和使用它。

5. 开源。GmSSL是开源的,任何人都可以查看和修改源代码,从而保证了它的安全性和可靠性。

GmSSL是一个重要的密码学工具包,它提供了对中国国家密码算法和协议的支持,并与OpenSSL兼容,使得开发人员可以快速地移植现有的OpenSSL项目。GmSSL的开源和易用性也使得它成为了广大开发人员的首选加密库之一。

1.2 openssl算法

密钥证书管理:

  1. 密钥和证书管理是PKI的一个重要组成部分,OpenSSL为之提供了丰富的功能,支持多种标准。
  2. 首先,OpenSSL实现了ASN.1的证书和密钥相关标准,提供了对证书、公钥、私钥、证书请求以及CRL等数据对象的DER、PEM和BASE64的编解码功能。OpenSSL提供了产生各种公开密钥对和对称密钥的方法、函数和应用程序,同时提供了对公钥和私钥的DER编解码功能。并实现了私钥的PKCS#12和PKCS#8的编解码功能。OpenSSL在标准中提供了对私钥的加密保护功能,使得密钥可以安全地进行存储和分发。
  3. 在此基础上,OpenSSL实现了对证书的X.509标准编解码、PKCS#12格式的编解码以及PKCS#7的编解码功能。并提供了一种文本数据库,支持证书的管理功能,包括证书密钥产生、请求产生、证书签发、吊销和验证等功能。
  4. 事实上,OpenSSL提供的CA应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书管理的大部分机制。
  5. SSL和TLS协议 :OpenSSL实现了SSL协议的SSLv2和SSLv3,支持了其中绝大部分算法协议。OpenSSL也实现了TLSv1.0,TLS是SSLv3的标准化版,虽然区别不大,但毕竟有很多细节不尽相同。

虽然已经有众多的软件实现了OpenSSL的功能,但是OpenSSL里面实现的SSL协议能够让我们对SSL协议有一个更加清楚的认识,因为至少存在两点:一是OpenSSL实现的SSL协议是开放源代码的,我们可以追究SSL协议实现的每一个细节;二是OpenSSL实现的SSL协议是纯粹的SSL协议,没有跟其它协议(如HTTP)协议结合在一起,澄清了SSL协议的本来面目。

对称加密:

OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。

非对称加密:

OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用于密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。

信息摘要:

OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法。此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。

1.3 gmssl算法

GmSSL是一个开源密码学工具包,它提供了对中国国家密码算法和协议的支持,包括以下算法:

  1. SM1对称加密算法:SM1是中国国家密码管理局推出的一种对称密码算法,基于特定的置换和S盒运算。
  2. SM2非对称加密算法:SM2是中国自主研发的一种ECC曲线加密算法,具有速度快、安全性高等特点。
  3. SM3哈希算法:SM3是中国自主研发的一种哈希算法,具有安全性高、效率高等特点。
  4. SM4对称加密算法:SM4是中国自主研发的一种分组密码算法,基于特定的S盒和置换运算。
  5. GM/T证书验证算法:中国政府制定的数字证书标准GM/T 0012规定了一种数字证书验证算法。

除了以上算法,GmSSL也支持其他常用的密码学算法和协议,如RSA、DSA、DH、TLS等。可以通过使用GmSSL来保证中国特定的密码标准和协议的安全性。

2 应用程序简介

2.1 应用场景

本实验的应用场景是数字电视条件接收系统中的加密与应用。数字电视条件接收系统(CAS)是指用来控制订户对广播服务或者节目进行接收的系统,通过该系统订户只能收看经过授权的广播服务或者节目。通过在电视台电视系统中对用户进行授权控制及授权管理,CAS系统实现了数据广播系统的有偿服务,这是实现为用户提供个性化服务的关键所在。加密算法是条件接收系统的功能及安全核心,一旦CAS中的算法被破解,整个系统即被破坏。因此,选择优秀的加密算法及合理的算法应用是CAS系统的核心问题。目前主流的CAS一般使用国外的加密算法,如属于对称算法的DES算法、3DES算法,属于非对称算法的RSA算法。而随着我国密码学研究的进步,我国也自主创新研发出一套商用密码,统称国密算法,其算法复杂度、安全性、应用性均已到达甚至超过国外算法。

2.2 系统模型

在CAS系统的标准模型中,整个系统是一套由3条密钥共同组成的加密系统,这3条密钥分别为加扰控制字CW、SK及根密钥PDK,3条密钥层层加密,环环相扣,构建了条件接收系统的安全体系。CAS主要分为两大部分:一是信号加扰部分,它是通过一个随机码发生器所产生的随机码(称为控制字CW)来控制加扰器对信号的加扰;二是加密部分,要使加扰的信号在接收端成功地解扰,接收端也必须要有和加扰端一模一样的控制字来控制解扰器,所以,要将前端的CW传送到接收端,如果直接传送会很容易被黑客截获而使CAS失去作用,为此,要对CW进行加密传送,这种加密是一种多层加密机制,从而增加CW传送的安全性,直接对CW加密的第一层所产生的密文称为授权控制信息ECM,通过复用器与加扰的码流一起传送,ECM还含有时间、节目价格、节目授权控制等信息,因此ECM是面向节目的管理信息。对CW加密的密钥称为工作密钥SK,SK通常又叫月密钥,每月换一次,每换一次SK,系统都要重新对所有用户进行授权。第二层加密是用称为节目密钥PDK对SK进行加密,所产生的密文和从SMS获取的授权指令通过SAS生成的授权信息组成授权管理信息EMM,EMM还含有智能卡号、授权时间、授权等级等用户授权信息。这些信息主要是完成对用户的授权,因此EMM是面向用户的管理信息,EMM对用户在什么时间看、看什么频道进行授权,它也通过复用器与加扰码流一起传送,以上这些组成了CAS最基本的加密系统。

2.3 密码算法使用及过程

在朱泽智等人的方案中,使用了SM4和SM2国密算法,本次实验拟使用SM3、SM4和SM2算法,对朱泽智等人的方案进行改进。

(1)根密钥生成使用

SM2算法生成根密钥对,其中私钥作为PDK置于终端,公钥则置于前端。

(2)SK生成

使用128位的SM4算法密钥。

(3)ECM加解密

前端使用SM4算法及SK作为密钥对CW加密形成ECM,终端同样使用SK作为密钥以SM4算法进行解密。

(4)EMM加解密

前端使用根密钥生成中的公钥对SK进行SM2加密形成EMM,终端使用PDK即私钥进行SM2解密。

由于对称算法效率较高,因此一般用于数据量相对大且对实时性要求较高的实时信道传输中;而非对称算法效率相对较低,但安全性更高,一般用于对数据量较少的信息的保护。因此两种算法一般共同使用,用高效的对称算法进行内容保护在信道中传输,并且信道中同时传送有非对称算法加密过的对称算法的密钥,在终端先用非对称算法对密钥进行解密,然后在用密钥对内容进行对称算法的解密。在CAS系统的场景中,ECM的数据量较大,且发送/接收频率较高,因此使用属于对称算法的SM4算法,而EMM数据量较少,发送/接收频率较低,但对安全性的要求更高,因此使用非对称的SM2算法。

2.4 算法改进

(1)哈希值计算

使用SM3算法,生成CW的HASH值,发给前端。

(2)根密钥生成使用

SM2算法生成根密钥对,其中私钥使用HASH进行加密,并作为PDK置于后端,公钥则置于前端。

(3)SK生成

前端使用128位的SM4算法密钥。

(4)ECM加解密

前端使用SM4算法及SK作为密钥对CW加密形成ECM,后端同样使用SK作为密钥以SM4算法进行解密。

(5)EMM加解密

前端使用根密钥生成中的公钥对SK进行SM2加密形成EMM,后端使用HASH值和私钥PDK进行SM2解密。

(6)校验完整性

后端使用解密出的CW计算64位hash值,进行比对HASH文件进行完整性检验。

3 代码

3.1 算法流程

用户:后端

setup:

cw,cw的HASH值

sm2生成的私钥使用(cw的hash的前64位)加密(sm4)生成pdk

Front:

接收cw,cw的hash,公钥,加密后的私钥

生成sk(sm4的128位密钥)

生成iv:pdk的hash前32位

使用sk和iv加密cw得到ecm(sm4)

公钥加密sk得到emm

emm、ecm、cw的hash发给后端

Rear:

cw的hash和pdk解密emm得到sk

sk和pdk(iv)解密得到cw

计算cw的hash(-d),对比

3.2 代码

setup.sh

#! /bin/bash
cd ./src
./m1
./m2
cd ..
cp ./Rear/PDK.pem ./Front/PDK.pem
echo "Setup FINISHED"

all.sh

#! /bin/sh
sh setup.sh
cd ./Front
sh trans.sh
cd ..
cd ./Rear
sh decrypt.sh
cd ..

src/make_cw.c

/*
 *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the License); you may
 *  not use this file except in compliance with the License.
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 */


#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <gmssl/mem.h>
#include <gmssl/rand.h>
#include <unistd.h>


static const char *options = "[-hex] [-rdrand] -outlen num [-out file]";

int gmrand(int argc, char **argv)
{
    int ret = 1;
    char *prog = argv[0];
    int hex = 0;
    int rdrand = 0;
    int outlen = 0;
    char *outfile = NULL;
    FILE *outfp = stdout;
    uint8_t buf[2048];

    argc--;
    argv++;

    if (argc < 1) {
        fprintf(stderr, "usage: %s %s\n", prog, options);
        return 1;
    }

    while (argc > 0) {
        if (!strcmp(*argv, "-help")) {
            printf("usage: %s %s\n", prog, options);
            ret = 0;
            goto end;
        } else if (!strcmp(*argv, "-hex")) {
            hex = 1;
        } else if (!strcmp(*argv, "-rdrand")) {
            rdrand = 1;
        } else if (!strcmp(*argv, "-outlen")) {
            if (--argc < 1) goto bad;
            outlen = atoi(*(++argv));
            if (outlen < 1 || outlen > INT_MAX) {
                fprintf(stderr, "%s: invalid outlen\n", prog);
                goto end;
            }
        } else if (!strcmp(*argv, "-out")) {
            if (--argc < 1) goto bad;
            outfile = *(++argv);
            if (!(outfp = fopen(outfile, "wb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
                goto end;
            }
        } else {
            fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
            goto end;
bad:
            fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
            goto end;
        }

        argc--;
        argv++;
    }

    if (!outlen) {
        fprintf(stderr, "%s: option -outlen missing\n", prog);
        goto end;
    }

    while (outlen > 0) {
        size_t len = outlen < sizeof(buf) ? outlen : sizeof(buf);

        if (rdrand) {
/*
            if (rdrand_bytes(buf, len) != 1) {
                fprintf(stderr, "%s: inner error\n", prog);
                goto end;
            }
*/
        } else {
            if (rand_bytes(buf, len) != 1) {
                fprintf(stderr, "%s: inner error\n", prog);
                goto end;
            }
        }

        if (hex) {
            int i;
            for (i = 0; i < len; i++) {
                fprintf(outfp, "%02X", buf[i]);
            }
        } else {
            if (fwrite(buf, 1, len, outfp) != len) {
                fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno));
                goto end;
            }
        }
        outlen -= (int)len;
    }
    if (hex) {
        fprintf(outfp, "\n");
    }
    ret = 0;
end:
    gmssl_secure_clear(buf, sizeof(buf));
    if (outfile && outfp) fclose(outfp);
    return ret;
}

int main(){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"rand");
    //strcpy(arg[1],"-hex");
    strcpy(arg[1],"-outlen");
    strcpy(arg[2],"6");
    strcpy(arg[3],"-out");
    strcpy(arg[4],"../Front/cw");
    gmrand(5,arg);

    return 0;
}

src/make_sm2_key.c

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/error.h>


static const char *usage_sm2 = "-pass str [-out pem] [-pubout pem]\n";

static const char *op_sm2 =
"Options\n"
"    -pass pass                  Password to encrypt the private key\n"
"    -out pem                    Output password-encrypted PKCS #8 private key in PEM format\n"
"    -pubout pem                 Output public key in PEM format\n"
"\n";

int sm2keygen(int argc, char **argv)
{
    int ret = 1;
    char *prog = argv[0];
    char *pass = NULL;
    char *outfile = NULL;
    char *puboutfile = NULL;
    FILE *outfp = stdout;
    FILE *puboutfp = stdout;
    SM2_KEY key;

    argc--;
    argv++;

    if (argc < 1) {
        fprintf(stderr, "usage_sm2: %s %s\n", prog, op_sm2);
        return 1;
    }

    while (argc > 0) {
        if (!strcmp(*argv, "-help")) {
            printf("usage_sm2: %s %s\n", prog, usage_sm2);
            printf("%s\n", op_sm2);
            ret = 0;
            goto end;
        } else if (!strcmp(*argv, "-pass")) {
            if (--argc < 1) goto bad;
            pass = *(++argv);
        } else if (!strcmp(*argv, "-out")) {
            if (--argc < 1) goto bad;
            outfile = *(++argv);
            if (!(outfp = fopen(outfile, "wb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
                goto end;
            }
        } else if (!strcmp(*argv, "-pubout")) {
            if (--argc < 1) goto bad;
            puboutfile = *(++argv);
            if (!(puboutfp = fopen(puboutfile, "wb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
                goto end;
            }
        } else {
            fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
            goto end;
bad:
            fprintf(stderr, "%s: `%s` option value missing\n", prog, *argv);
            goto end;
        }

        argc--;
        argv++;
    }

    if (!pass) {
        fprintf(stderr, "%s: `-pass` option required\n", prog);
        goto end;
    }

    if (sm2_key_generate(&key) != 1
        || sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1
        || sm2_public_key_info_to_pem(&key, puboutfp) != 1) {
        fprintf(stderr, "%s: inner failure\n", prog);
        goto end;
    }
    ret = 0;

end:
    gmssl_secure_clear(&key, sizeof(key));
    if (outfile && outfp) fclose(outfp);
    if (puboutfile && puboutfp) fclose(puboutfp);
    return ret;
}

static const char *op_sm3 = "[-hex|-bin] [-pubkey pem [-id str]] [-in file] [-out file]";

int sm3(int argc, char **argv)
{
    int ret = 1;
    char *prog = argv[0];
    int bin = 0;
    char *pubkeyfile = NULL;
    char *infile = NULL;
    char *outfile = NULL;
    char *id = NULL;
    FILE *pubkeyfp = NULL;
    FILE *infp = stdin;
    FILE *outfp = stdout;
    SM3_CTX sm3_ctx;
    uint8_t dgst[32];
    uint8_t buf[4096];
    size_t len;
    int i;

    argc--;
    argv++;

    while (argc > 0) {
        if (!strcmp(*argv, "-help")) {
            printf("usage: %s %s\n", prog, op_sm3);
            printf("usage: echo -n \"abc\" | %s\n", prog);
            ret = 0;
            goto end;
        } else if (!strcmp(*argv, "-hex")) {
            if (bin) {
                error_print();
                goto end;
            }
            bin = 0;
        } else if (!strcmp(*argv, "-bin")) {
            bin = 1;
        } else if (!strcmp(*argv, "-pubkey")) {
            if (--argc < 1) goto bad;
            pubkeyfile = *(++argv);
            if (!(pubkeyfp = fopen(pubkeyfile, "rb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno));
                goto end;
            }
        } else if (!strcmp(*argv, "-id")) {
            if (--argc < 1) goto bad;
            id = *(++argv);
        } else if (!strcmp(*argv, "-in")) {
            if (--argc < 1) goto bad;
            infile = *(++argv);
            if (!(infp = fopen(infile, "rb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
                goto end;
            }
        } else if (!strcmp(*argv, "-out")) {
            if (--argc < 1) goto bad;
            outfile = *(++argv);
            if (!(outfp = fopen(outfile, "wb"))) {
                fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
                goto end;
            }
        } else {
            fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
            goto end;
bad:
            fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
            goto end;
        }

        argc--;
        argv++;
    }

    sm3_init(&sm3_ctx);

    if (pubkeyfile) {
        SM2_KEY sm2_key;
        uint8_t z[32];

        if (sm2_public_key_info_from_pem(&sm2_key, pubkeyfp) != 1) {
            fprintf(stderr, "%s: parse public key failed\n", prog);
            goto end;
        }
        if (!id) {
            id = SM2_DEFAULT_ID;
        }

        sm2_compute_z(z, (SM2_POINT *)&sm2_key, id, strlen(id));
        sm3_update(&sm3_ctx, z, sizeof(z));
    } else {
        if (id) {
            fprintf(stderr, "%s: option '-id' must be with '-pubkey'\n", prog);
            goto end;
        }
    }

    while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) {
        sm3_update(&sm3_ctx, buf, len);
    }
    sm3_finish(&sm3_ctx, dgst);

    if (bin) {
        if (fwrite(dgst, 1, sizeof(dgst), outfp) != sizeof(dgst)) {
            fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno));
            goto end;
        }
    } else {
        for (i = 0; i < sizeof(dgst); i++) {
            fprintf(outfp, "%02x", dgst[i]);
        }
        fprintf(outfp, "\n");
    }
    ret = 0;
end:
    if (pubkeyfp) fclose(pubkeyfp);
    if (infile && infp) fclose(infp);
    if (outfile && outfp) fclose(outfp);
    return ret;
}

int make_HASH(char *cw,char *HASH){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm3");
    strcpy(arg[1],"-hex");
    strcpy(arg[2],"-in");
    strcpy(arg[3],cw);
    strcpy(arg[4],"-out");
    strcpy(arg[5],"../Front/HASH");
    sm3(6, arg);

    FILE *f = fopen("../Front/HASH","r");
    fread(HASH,1,64,f);
    fclose(f);
    HASH[64]='\0';
}

int main()
{
    char *cw="../Front/cw";
    char **arg=(char **)malloc(7*sizeof(char*));
    for(int i=0;i<7;i++) arg[i]=(char*)malloc(65*sizeof(char));

    strcpy(arg[0],"sm2keygen");
    strcpy(arg[1],"-pass");
    make_HASH(cw,arg[2]);
    //printf("%s\n",arg[2]);
    strcpy(arg[3],"-out");
    strcpy(arg[4],"../Rear/PDK.pem");
    strcpy(arg[5],"-pubout");
    strcpy(arg[6],"../Front/PUBK.pem");
    sm2keygen(7,arg);
    return 0;
}

front/trans.sh

#! /bin/bash
cd ./src
./front
echo "Encrypt FINISHED"
cd ..
rm cw
rm PDK.pem
rm PUBK.pem
mv ECM ../Rear/ECM
mv EMM ../Rear/EMM
mv HASH ../Rear/HASH
echo "Transmitted"

front/src/front.c

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/hex.h>
#include <gmssl/aead.h>
#include <gmssl/error.h>
#include "../tools/sm2encrypt.c"
#include "../tools/rand.c"
#include "../tools/sm4.c"
#include "../tools/sm3.c"

static int iv_len=32;
static int key_len=32;
int make_SK(char *sk){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"rand");
    strcpy(arg[1],"-hex");
    strcpy(arg[2],"-outlen");
    strcpy(arg[3],"32");
    strcpy(arg[4],"-out");
    strcpy(arg[5],"sk");
    rand_main(6, arg);

    FILE *f = fopen("sk","r");
    fread(sk,1,key_len,f);
    fclose(f);
    sk[key_len]='\0';
}
int make_IV(char *PDK,char *iv){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm3");
    strcpy(arg[1],"-hex");
    strcpy(arg[2],"-in");
    strcpy(arg[3],PDK);
    strcpy(arg[4],"-out");
    strcpy(arg[5],"iv");
    sm3_main(6, arg);

    FILE *f = fopen("iv","r");
    fread(iv,1,iv_len,f);
    fclose(f);
    iv[iv_len]='\0';
    system("rm iv");
}
int encrypt_cw_bysm4(char *ECM,char *cw,char *iv,char *sk){
    char **arg=(char **)malloc(11*sizeof(char*));
    for(int i=0;i<11;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm4");
    strcpy(arg[1],"-gcm");
    strcpy(arg[2],"-encrypt");
    strcpy(arg[3],"-key");
    strcpy(arg[4],sk);
    strcpy(arg[5],"-iv");
    strcpy(arg[6],iv);
    strcpy(arg[7],"-in");
    strcpy(arg[8],cw);
    strcpy(arg[9],"-out");
    strcpy(arg[10],ECM);
    
    sm4_main(11, arg);
}
int encrypt_sk_bysm2(char *EMM,char *PUBK,char *sk){
    char **arg=(char **)malloc(7*sizeof(char*));
    for(int i=0;i<7;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm2encrypt");
    strcpy(arg[1],"-pubkey");
    strcpy(arg[2],PUBK);
    strcpy(arg[3],"-in");
    strcpy(arg[4],"sk");
    strcpy(arg[5],"-out");
    strcpy(arg[6],EMM);
    sm2encrypt_main(7, arg);
    system("rm sk");
}
int main(){
    char *sk;
    sk=(char*)malloc(32*sizeof(char));
    char *iv;
    iv=(char*)malloc(32*sizeof(char));
    char *cw="../cw";
    char *ECM="../ECM";
    char *EMM="../EMM";
    char *PUBK="../PUBK.pem";
    char *PDK="../PDK.pem";
    
    make_SK(sk);
    make_IV(PDK,iv);
    encrypt_cw_bysm4(ECM,cw,iv,sk);
    encrypt_sk_bysm2(EMM,PUBK,sk);

    return 0;
}

rear/decrypt.sh

#! /bin/sh
cd ./src
./rear
echo "Decrypt FINISHED"
cd ..
echo ""
echo "Integrity Verification:"
echo "  HASH:"
od -tx1 HASH
echo "  HASH_d:"
od -tx1 HASH_d
diff -c HASH HASH_d
rm cw
rm PDK.pem
rm HASH
rm HASH_d
rm ECM
rm EMM 

rear/src/rear.c

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/hex.h>
#include <gmssl/aead.h>
#include <gmssl/error.h>
#include "../tools/sm2decrypt.c"
#include "../tools/rand.c"
#include "../tools/sm4.c"
#include "../tools/sm3.c"

static int iv_len=32;
static int key_len=32;
int make_IV(char *PDK,char *iv){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm3");
    strcpy(arg[1],"-hex");
    strcpy(arg[2],"-in");
    strcpy(arg[3],PDK);
    strcpy(arg[4],"-out");
    strcpy(arg[5],"iv");
    sm3_main(6, arg);

    FILE *f = fopen("iv","r");
    fread(iv,1,iv_len,f);
    fclose(f);
    iv[iv_len]='\0';
    system("rm iv");
}
int decrypt_cw_bysm4(char *ECM,char *cw,char *iv,char *sk){
    char **arg=(char **)malloc(11*sizeof(char*));
    for(int i=0;i<11;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm4");
    strcpy(arg[1],"-gcm");
    strcpy(arg[2],"-decrypt");
    strcpy(arg[3],"-key");
    strcpy(arg[4],sk);
    strcpy(arg[5],"-iv");
    strcpy(arg[6],iv);
    strcpy(arg[7],"-in");
    strcpy(arg[8],ECM);
    strcpy(arg[9],"-out");
    strcpy(arg[10],cw);
    
    sm4_main(11, arg);
}
int decrypt_sk_bysm2(char *EMM,char *PDK,char *sk,char *pass){
    char **arg=(char **)malloc(9*sizeof(char*));
    for(int i=0;i<9;i++) arg[i]=(char*)malloc(65*sizeof(char));

    strcpy(arg[0],"sm2decrypt");
    strcpy(arg[1],"-key");
    strcpy(arg[2],PDK);
    strcpy(arg[3],"-pass");
    FILE *f = fopen(pass,"r");
    fread(arg[4],1,64,f);
    fclose(f);
    arg[4][64] = '\0';
    strcpy(arg[5],"-in");
    strcpy(arg[6],EMM);
    strcpy(arg[7],"-out");
    strcpy(arg[8],"sk");
    
    sm2decrypt_main(9, arg);
    f = fopen("sk","r");
    fread(sk,1,32,f);
    fclose(f);
    system("rm sk");    
}
void HASH(char *cw){
    char **arg=(char **)malloc(6*sizeof(char*));
    for(int i=0;i<6;i++) arg[i]=(char*)malloc(33*sizeof(char));

    strcpy(arg[0],"sm3");
    strcpy(arg[1],"-hex");
    strcpy(arg[2],"-in");
    strcpy(arg[3],cw);
    strcpy(arg[4],"-out");
    strcpy(arg[5],"../HASH_d");
    sm3_main(6, arg);
}
int main(){
    char *sk;
    sk=(char*)malloc(key_len*sizeof(char));
    char *iv;
    iv=(char*)malloc(iv_len*sizeof(char));
    char *cw="../cw";
    char *ECM="../ECM";
    char *EMM="../EMM";
    char *PDK="../PDK.pem";
    char *pass="../HASH";
    
    make_IV(PDK,iv);
    decrypt_sk_bysm2(EMM,PDK,sk,pass); 
    decrypt_cw_bysm4(ECM,cw,iv,sk);
    HASH(cw);
    return 0;
}

tools文件夹:算法库(sm2、sm3、sm4等)

4 运行

sh all.sh

 

posted @ 2023-06-14 16:23  20201202史婧怡  阅读(66)  评论(0编辑  收藏  举报