网络对抗期末(二~四)
加密实验室
实验二~四:密钥加密实验室、单向哈希函数实验室、公钥加密和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算法
密钥证书管理:
- 密钥和证书管理是PKI的一个重要组成部分,OpenSSL为之提供了丰富的功能,支持多种标准。
- 首先,OpenSSL实现了ASN.1的证书和密钥相关标准,提供了对证书、公钥、私钥、证书请求以及CRL等数据对象的DER、PEM和BASE64的编解码功能。OpenSSL提供了产生各种公开密钥对和对称密钥的方法、函数和应用程序,同时提供了对公钥和私钥的DER编解码功能。并实现了私钥的PKCS#12和PKCS#8的编解码功能。OpenSSL在标准中提供了对私钥的加密保护功能,使得密钥可以安全地进行存储和分发。
- 在此基础上,OpenSSL实现了对证书的X.509标准编解码、PKCS#12格式的编解码以及PKCS#7的编解码功能。并提供了一种文本数据库,支持证书的管理功能,包括证书密钥产生、请求产生、证书签发、吊销和验证等功能。
- 事实上,OpenSSL提供的CA应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书管理的大部分机制。
- 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是一个开源密码学工具包,它提供了对中国国家密码算法和协议的支持,包括以下算法:
- SM1对称加密算法:SM1是中国国家密码管理局推出的一种对称密码算法,基于特定的置换和S盒运算。
- SM2非对称加密算法:SM2是中国自主研发的一种ECC曲线加密算法,具有速度快、安全性高等特点。
- SM3哈希算法:SM3是中国自主研发的一种哈希算法,具有安全性高、效率高等特点。
- SM4对称加密算法:SM4是中国自主研发的一种分组密码算法,基于特定的S盒和置换运算。
- 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