# 课设实验报告 小组总和

## 课设实验报告 小组总和

《信息安全工程技术应用》课程设计报告

20201327 刘谨铭
20201310 何忠鑫
20201303 张奕博

### 通过gm-crypto密码算法库实现国密算法

#### SM2


const { SM2 } = require('gm-crypto')

const { publicKey, privateKey } = SM2.generateKeyPair()
const originalData = '20201327ljm'

const encryptedData = SM2.encrypt(originalData, publicKey, {
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
console.log(encryptedData)

const decryptedData = SM2.decrypt(encryptedData, privateKey, {
inputEncoding: 'base64',
outputEncoding: 'utf8'
})
console.log(decryptedData)


#### SM3

const { SM3 } = require('gm-crypto')

console.log(SM3.digest('20201327'))
console.log(SM3.digest('ljm', 'base64'))
console.log(SM3.digest('415', 'hex', 'base64'))



#### SM4

const { SM4 } = require('gm-crypto')

const key = '0123456789abcdeffedcba9876543210' // Any string of 32 hexadecimal digits
const originalData = '20201327ljm'

/**
* Block cipher modes:
* - ECB: electronic codebook
* - CBC: cipher block chaining
*/

let encryptedData, decryptedData

// ECB
encryptedData = SM4.encrypt(originalData, key, {
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
console.log(encryptedData)

decryptedData = SM4.decrypt(encryptedData, key, {
inputEncoding: 'base64',
outputEncoding: 'utf8'
})
console.log(decryptedData)

console.log('\n')

// CBC
const iv = '0123456789abcdeffedcba9876543210' // Initialization vector(any string of 32 hexadecimal digits)
encryptedData = SM4.encrypt(originalData, key, {
iv,
mode: SM4.constants.CBC,
inputEncoding: 'utf8',
outputEncoding: 'hex'
})
console.log(encryptedData)

decryptedData = SM4.decrypt(encryptedData, key, {
iv,
mode: SM4.constants.CBC,
inputEncoding: 'hex',
outputEncoding: 'utf8'
})
console.log(decryptedData)


### 通过sm-crypto密码算法库实现国密算法

#### sm2

const sm2 = require("miniprogram-sm-crypto").sm2;

let keypair = sm2.generateKeyPairHex();

publicKey = keypair.publicKey; // 公钥
privateKey = keypair.privateKey; // 私钥

const cipherMode = 1; // 1 - C1C3C2，0 - C1C2C3，默认为1

let encryptData = sm2.doEncrypt('20201327', publicKey, cipherMode); // 加密结果
console.log(encryptData)
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode); // 解密结果
console.log(decryptData)


#### sm3

const sm3 = require("miniprogram-sm-crypto").sm3;

let hashData = sm3("20201327"); // 杂凑
console.log(hashData)


#### sm4

const sm4 = require("miniprogram-sm-crypto").sm4;
const key = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10];

let encryptData = sm4.encrypt("20201327", key); // 加密
console.log(encryptData)

let decryptData = sm4.decrypt(encrytData, key); // 解密

console.log(decryptData)


### python实现sm4

#### 通过gmssl

##############################################################################
#                                                                            #
#                            国产SM4加密算法                                  #
#                                                                            #
##############################################################################

import binascii

from gmssl import sm4

class SM4:
"""
国产加密 sm4加解密
"""

def __init__(self):
self.crypt_sm4 = sm4.CryptSM4()  # 实例化

def str_to_hexStr(self, hex_str):
"""
字符串转hex
:param hex_str: 字符串
:return: hex
"""
hex_data = hex_str.encode('utf-8')
str_bin = binascii.unhexlify(hex_data)
return str_bin.decode('utf-8')

def encryptSM4(self, encrypt_key, value):
"""
国密sm4加密
:param encrypt_key: sm4加密key
:param value: 待加密的字符串
:return: sm4加密后的十六进制值
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(encrypt_key.encode(), sm4.SM4_ENCRYPT)  # 设置密钥
date_str = str(value)
encrypt_value = crypt_sm4.crypt_ecb(date_str.encode())  # 开始加密。bytes类型
return encrypt_value.hex()  # 返回十六进制值

def decryptSM4(self, decrypt_key, encrypt_value):
"""
国密sm4解密
:param decrypt_key:sm4加密key
:param encrypt_value: 待解密的十六进制值
:return: 原字符串
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(decrypt_key.encode(), sm4.SM4_DECRYPT)  # 设置密钥
decrypt_value = crypt_sm4.crypt_ecb(bytes.fromhex(encrypt_value))  # 开始解密。十六进制类型
return decrypt_value.decode()
# return self.str_to_hexStr(decrypt_value.hex())

if __name__ == '__main__':
key = "f38fc9b32af486e65d6f93dbc41b9123"
strData = "90897h8789thvht"
SM4 = SM4()
print("原字符：", strData)
encData = SM4.encryptSM4(key, strData)  # 加密后的数据，返回bytes类型
print("sm4加密结果：", encData)

decData = SM4.decryptSM4(key, encData)
print("sm4解密结果：", decData)  # 解密后的数据



### python通过gmssl实现sm2

import sys
from gmssl import sm2
from base64 import b64encode, b64decode
# sm2的公私钥
SM2_PRIVATE_KEY = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'

sm2_crypt = sm2.CryptSM2(public_key=SM2_PUBLIC_KEY, private_key=SM2_PRIVATE_KEY)

# 加密
def encrypt(info):
encode_info = sm2_crypt.encrypt(info.encode(encoding="utf-8"))
encode_info = b64encode(encode_info).decode()  # 将二进制bytes通过base64编码
return encode_info

# 解密
def decrypt(info):
decode_info = b64decode(info.encode())  # 通过base64解码成二进制bytes
decode_info = sm2_crypt.decrypt(info).decode(encoding="utf-8")
return decode_info

if __name__ == "__main__":
action = sys.argv[1]  # 取命令中的加解密动作
contact_info = sys.argv[2]  # 取命令中需要加解密的内容
if action == "encrypt":
encrypted_contact_info = encrypt(contact_info)
print(encrypted_contact_info)
if action == "decrypt":
decrypted_contact_info = decrypt(contact_info)
print(decrypted_contact_info)



### 改进

from gmssl import sm2
# sm2的公私钥
SM2_PRIVATE_KEY = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'

sm2_crypt = sm2.CryptSM2(public_key=SM2_PUBLIC_KEY, private_key=SM2_PRIVATE_KEY)

# 加密
def encrypt(info):
encode_info = sm2_crypt.encrypt(info.encode(encoding="utf-8"))
return encode_info

# 解密
def decrypt(info):
decode_info = sm2_crypt.decrypt(info).decode(encoding="utf-8")
return decode_info

if __name__ == "__main__":
info = "123456"
encode_info = encrypt(info)
print(encode_info)
decode_info = decrypt(encode_info)
print(decode_info)



### pysmx实现国密算法

#### sm2的签名验签

##### 生成密钥
from pysmx.SM2 import generate_keypair
pk, sk = generate_keypair()

##### 签名
from pysmx.SM2 import Sign
len_para = 64
sig = Sign("hello", sk, '123456', len_para)

##### 验签
from pysmx.SM2 import Verify
len_para = 64
Verify(sig, "hello", pk, len_para)  //True
Verify(sig, "Hello", pk, len_para)  //False


#### sm2加密解密

from pysmx.SM2 import Encrypt
e = b'20201327'
len_para = 64
C = Encrypt(e, pk, len_para, 0)  # 此处的1代表e是否是16进制字符串
print(C)
m = Decrypt(C, sk, len_para)
print(m)


#### sm3

//方法一
from pysmx.SM3 import SM3
sm3 = SM3()
sm3.update('20201327ljm')
m=sm3.hexdigest()
print(m)

//方法二
from pysmx.SM3 import hash_msg
s = '20201327ljm'
n=hash_msg(s)
print(n)


#### sm4

//加密
from pysmx.SM4 import Sm4, ENCRYPT, DECRYPT
key_data = b'1111222233334444'  # 至少16字节
sm4 = Sm4()
input_data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
sm4.sm4_set_key(key_data, ENCRYPT)
msg = sm4.sm4_crypt_ecb(input_data)
print(msg)
//解密
sm4.sm4_set_key(key_data, DECRYPT)
m=sm4.sm4_crypt_ecb(msg)
print(m)


### 检查对称算法

SM4-自测试数据

/** 文件名: https://github.com/liuqun/openssl-sm4-demo/blob/cmake/src/main.c */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/err.h"
#include "openssl/evp.h"

/* Before OpenSSL 1.1.1-pre1, we did not have EVP_sm4_ecb() */
#if defined(OPENSSL_VERSION_NUMBER) \
&& OPENSSL_VERSION_NUMBER < 0x10101001L
static const EVP_CIPHER *(*EVP_sm4_ecb)()=EVP_aes_128_ecb;
#endif

typedef struct {
const unsigned char *in_data;
size_t in_data_len;
const unsigned char *in_ivec;
const unsigned char *in_key;
size_t in_key_len;
} test_case_t;

void test_encrypt_with_cipher(const test_case_t *in, const EVP_CIPHER *cipher)
{
unsigned char *out_buf = NULL;
int out_len;
EVP_CIPHER_CTX *ctx;

ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, cipher, NULL, in->in_key, in->in_ivec);

{
And its length must be an integral multiple of the cipher's block size. */
const size_t bs = EVP_CIPHER_block_size(cipher);
if (in->in_data_len % bs != 0)
{
printf("ERROR-1: data length=%d which is not added yet; block size=%d\n", (int) in->in_data_len, (int) bs);
/* Warning: Remember to do some clean-ups */
EVP_CIPHER_CTX_free(ctx);
return;
}
/* Disable the implicit PKCS#7 padding defined in EVP_CIPHER */
}

out_buf = (unsigned char *) malloc(((in->in_data_len>>4)+1) << 4);
out_len = 0;
EVP_EncryptUpdate(ctx, out_buf, &out_len, in->in_data, in->in_data_len);
if (1)
{
printf("Debug: out_len=%d\n", out_len);
}

if (1)
{
}

EVP_CIPHER_CTX_free(ctx);
if (1)
{
int i;
int len;
for (i=0; i<len; i++)
{
printf("%02x ", out_buf[i]);
}
printf("\n");
}

if (out_buf)
{
free(out_buf);
out_buf = NULL;
}
}

void main()
{
int have_sm4 = (OPENSSL_VERSION_NUMBER >= 0x10101001L);
int have_aes = 1;
const unsigned char data[]=
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
unsigned char ivec[EVP_MAX_IV_LENGTH]; ///< IV 向量
const unsigned char key1[16] = ///< key_data, 密钥内容, 至少16字节
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
test_case_t tc;

tc.in_data = data;
tc.in_data_len = sizeof(data);
tc.in_data_is_already_padded = (tc.in_data_len % 16)==0; // Hard coded 16 as the cipher's block size
tc.in_key = key1;
tc.in_key_len = sizeof(key1);
memset(ivec, 0x00, EVP_MAX_IV_LENGTH);
tc.in_ivec = ivec;

#if defined(OPENSSL_NO_SM4)
have_sm4 = 0;
#endif
if (have_sm4)
{
printf("[1]\n");
printf("Debug: EVP_sm4_ecb() test\n");
test_encrypt_with_cipher(&tc, EVP_sm4_ecb());
}
#if defined(OPENSSL_NO_AES)
have_aes = 0;
#endif
if (have_aes)
{
printf("[2]\n");
printf("Debug: EVP_aes_128_ecb() test\n");
test_encrypt_with_cipher(&tc, EVP_aes_128_ecb());
}
}



### sm3直接加密文件

1.babassl
ZUC算法代码：

#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>

int main(int argc, char *argv[])
{
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL;
unsigned char *got = NULL;
size_t got_len;
char *mac;
int rv;
const char key[] = {
0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb,
0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a
};
/*
* EIA3 的 iv 只有5个字节(只用到38bit)，不是随机构造，构造方法如下：
* |----------32bit----------|-----5bit-----|---1bit---|
* |          count          |    bearer    | direction|
*/
const char *iv = "a94059da54";
const char msg[] = {
0x98, 0x3b, 0x41, 0xd4, 0x7d, 0x78, 0x0c, 0x9e,
0x1a, 0xd1, 0x1d, 0x7e, 0xb7, 0x03, 0x91, 0xb1,
0xde, 0x0b, 0x35, 0xda, 0x2d, 0xc6, 0x2f, 0x83,
0xe7, 0xb7, 0x8d, 0x63, 0x06, 0xca, 0x0e, 0xa0,
0x7e, 0x94, 0x1b, 0x7b, 0xe9, 0x13, 0x48, 0xf9,
0xfc, 0xb1, 0x70, 0xe2, 0x21, 0x7f, 0xec, 0xd9,
0x7f, 0x9f, 0x68, 0xad, 0xb1, 0x6e, 0x5d, 0x7d,
0x21, 0xe5, 0x69, 0xd2, 0x80, 0xed, 0x77, 0x5c,
0xeb, 0xde, 0x3f, 0x40, 0x93, 0xc5, 0x38, 0x81,
0x00
};
size_t msg_len = 73;

/*
* 将 EIA3 的 key 转换成 EVP_PKEY
*/
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_EIA3, NULL, key, 16);
if (pkey == NULL)
goto end;

mctx = EVP_MD_CTX_new();
if (mctx == NULL)
goto end;

if (!EVP_DigestSignInit(mctx, &pctx, NULL, NULL, pkey))
goto end;

/*
* 设置 EIA3 的 iv，其中 iv 是十六进制的字符串形式
* 也可以设置 hexkey 来修改 key，同样是十六进制的字符吕形式
*/
rv = EVP_PKEY_CTX_ctrl_str(pctx, "iv", iv);
if (rv <= 0)
goto end;

if (!EVP_DigestSignUpdate(mctx, msg, msg_len))
goto end;

if (!EVP_DigestSignFinal(mctx, NULL, &got_len))
goto end;

got = OPENSSL_malloc(got_len);
if (got == NULL)
goto end;

if (!EVP_DigestSignFinal(mctx, got, &got_len))
goto end;

/*
* EIA3 的 mac 值为4个字节，这里打印出来
*/
mac = OPENSSL_buf2hexstr(got, got_len);
printf("MAC=%s\n", mac);

OPENSSL_free(mac);

end:
EVP_MD_CTX_free(mctx);
OPENSSL_free(got);
EVP_PKEY_free(pkey);

return 0;
}



ZUC测试截图

SM2代码：

//生成SM2私钥
openssl ecparam -genkey -name SM2 -out sm2.key

//生成证书签名请求 csr
openssl req -new -key sm2.key -out sm2.csr -sm3 -sigopt "sm2_id:1234567812345678"
//自签名测试证书
openssl x509 -req -in sm2.csr -signkey sm2.key -out sm2.crt -sm3 -sm2-id 1234567812345678 -sigopt "sm2_id:1234567812345678"


SM2测试截图

2.gmlib
SM3测试代码：

﻿#include<gmlib/utils.h>
#include<gmlib/hash/sm3.h>
int main() {
SM3_CTX sm3_ctx;
uint8_t msg[] = {'a', 'b', 'c'};  // 原始消息
uint8_t digest[SM3_DIGEST_SIZE];  // 消息摘要

// 初始化 SM3
sm3_init(&sm3_ctx);
// 输入消息
sm3_update(msg, sizeof(msg), &sm3_ctx);
// 结束 SM3 并输出摘要 digest
sm3_final(digest, &sm3_ctx);

dump_data(digest, sizeof(digest));
/*  SM3 摘要结果
66 c7 f0 f4 62 ee ed d9 d1 f2 d4 6b dc 10 e4 e2
41 67 c4 87 5c f2 f7 a2 29 7d a0 2b 8f 4b a8 e0
*/
return 0;
}



SM4测试代码：

#include <gmlib/cipher/mode.h>
#include <gmlib/cipher/sm4.h>
#include <gmlib/err.h>
#include <gmlib/utils.h>

static uint8_t sm4_key[SM4_KEYLEN] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};

static uint8_t sm4_pt[SM4_BLOCK_SIZE] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
};

static uint8_t out[SM4_BLOCK_SIZE * 2];

int main() {
SM4_CTX sm4key;
sm4_init(sm4_key, &sm4key);
sm4_encrypt(out, sm4_pt, &sm4key);
// 09 32 5c 48 53 83 2d cb 93 37 a5 98 4f 67 1b 9a
dump_data(out, SM4_BLOCK_SIZE);

ECB_CTX ctx;
uint8_t* outptr = out;
int outl;
ecb_init(sm4_key, &SM4Info, &sm4key, &ctx);
ecb_encrypt_update(outptr, &outl, sm4_pt, sizeof(sm4_pt), &ctx);
outptr += outl;
ecb_encrypt_final(outptr, &outl, &ctx);
outptr += outl;
// 09 32 5c 48 53 83 2d cb 93 37 a5 98 4f 67 1b 9a
// 00 2a 8a 4e fa 86 3c ca d0 24 ac 03 00 bb 40 d2
dump_data(out, (int)(outptr - out));

return 0;
}



tjfoc-gm


package main

import (
"bytes"
"crypto/cipher"
"crypto/rand"
"fmt"
"log"

"github.com/Hyperledger-TWGC/tjfoc-gm/sm2"
"github.com/Hyperledger-TWGC/tjfoc-gm/sm3"
"github.com/Hyperledger-TWGC/tjfoc-gm/sm4"
)

func main() {
SM2()

SM3()

SM4()
}

func SM2() {
priv, err := sm2.GenerateKey(rand.Reader) // 生成密钥对
if err != nil {
log.Fatal(err)
}
msg := []byte("Tongji Fintech Research Institute")
pub := &priv.PublicKey
ciphertxt, err := sm2.Encrypt(pub, msg, rand.Reader)
if err != nil {
log.Fatal(err)
}
fmt.Println("SM2加密密文是：", string(msg))
fmt.Printf("SM2加密结果是：%x\n", ciphertxt)

plaintxt, err := priv.Decrypt(nil, ciphertxt, nil)
if err != nil {
log.Fatal(err)
}
if !bytes.Equal(msg, plaintxt) {
log.Fatal("原文不匹配")
}

sign, err := priv.Sign(rand.Reader, msg, nil)
if err != nil {
log.Fatal(err)
}

isok := priv.PublicKey.Verify(msg, sign)
fmt.Printf("SM2 Verified: %v\n", isok)
}

func SM3() {
data := "test"
h := sm3.New()
h.Write([]byte(data))
sum := h.Sum(nil)
fmt.Printf("SM3 digest value is: %x\n", sum)
}

func SM4() {
// 128比特密钥
key := []byte("1234567890abcdef")
// 128比特iv
iv := make([]byte, sm4.BlockSize)
data := []byte("Tongji Fintech Research Institute")
fmt.Println("SM4加密密文是：", string(data))
ciphertxt, err := sm4Encrypt(key, iv, data)
if err != nil {
log.Fatal(err)
}
fmt.Printf("SM4加密结果: %x\n", ciphertxt)

res, err := sm4Decrypt(key, iv, ciphertxt)
if err != nil {
log.Fatal(err)
}
fmt.Printf("SM4解密结果: %x\n", res)
fmt.Println("SM4解密密文是：", string(res))
}

func sm4Encrypt(key, iv, plainText []byte) ([]byte, error) {
block, err := sm4.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCEncrypter(block, iv)
cryted := make([]byte, len(origData))
blockMode.CryptBlocks(cryted, origData)
return cryted, nil
}

func sm4Decrypt(key, iv, cipherText []byte) ([]byte, error) {
block, err := sm4.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, iv)
origData := make([]byte, len(cipherText))
blockMode.CryptBlocks(origData, cipherText)
return origData, nil
}

// pkcs5填充
func pkcs5Padding(src []byte, blockSize int) []byte {
}

length := len(src)
if length == 0 {
return nil
}
}


crypto++

#include "pch.h"
#include <string>
#include <cstring>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include "cryptopp/aes.h"
#include "cryptopp/filters.h"
#include "cryptopp/modes.h"
using namespace std;
using namespace CryptoPP;

byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE];

void initKV() {
memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH);
memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE);
}

string encrypt(string plainText) {
string cipherText;

CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);
CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(cipherText));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plainText.c_str()), plainText.length() + 1);
stfEncryptor.MessageEnd();

string cipherTextHex;
for (int i = 0; i < cipherText.size(); i++)
{
char ch[3] = { 0 };
sprintf_s(ch, "%02x", static_cast<byte>(cipherText[i]));
cipherTextHex += ch;
}

return cipherTextHex;
}

int main() {
string text = "20201303zyb";
cout << "text : " << text << endl;

initKV();
string cipherHex = encrypt(text);
cout << "cipher : " << cipherHex << endl;
}


Miracl

#include <stdio.h>
#include <string.h>
#include <time.h>

#include "sm9/sm9_algorithm.h"
#include "sm9/print_out.h"

#define TEST 100

int main(int argc, char **argv)
{
printf("20201303begin test \n");
//===========签名用到的参数==========
unsigned char cks[32] = "\x86\xDC\xD6\x4F\xEB\x81\xA7\x19\x63\x59\x59\xF1\xA5\xC2\xF9\x88\xBD\x39\x43\x1B\x08\xA8\x63\xF0\x42\x8D\x21\xDF\xFA\xF2\xBF\x89";
unsigned char id[5] = {"\x41\x6C\x69\x63\x65"};
unsigned char rand[32] = {"\x1A\x23\x29\x77\xBA\x9F\xA2\xD1\xC5\x58\xF2\xD4\x67\xFE\x7B\xE7\x04\x05\x41\x26\x73\xF8\xBE\x64\x9B\xBD\xD4\xA0\x95\xBE\x1B\x4B"};
unsigned char msg[20] = {"\x43\x68\x69\x6E\x65\x73\x65\x20\x49\x42\x53\x20\x73\x74\x61\x6E\x64\x61\x72\x64"};
//========加密用到的参数===================
unsigned char cmsg[20] = {"\x43\x68\x69\x6E\x65\x73\x65\x20\x49\x42\x45\x20\x73\x74\x61\x6E\x64\x61\x72\x64"};
unsigned char eid[3] = {"\x42\x6F\x62"};
unsigned char er[32] = {"\x00\x00\xAA\xC0\x54\x17\x79\xC8\xFC\x45\xE3\xE2\xCB\x25\xC1\x2B\x5D\x25\x76\xB2\x12\x9A\xE8\xBB\x5E\xE2\xCB\xE5\xEC\x9E\x78\x5C"};
unsigned char plain[32];
unsigned int plainlen;
//==============密钥交换用到的参数================
unsigned char kks[32] = {"\x00\x02\xE6\x5B\x07\x62\xD0\x42\xF5\x1F\x0D\x23\x54\x2B\x13\xED\x8C\xFA\x2E\x9A\x0E\x72\x06\x36\x1E\x01\x3A\x28\x39\x05\xE3\x1F"};
unsigned char alice[5] = {"\x41\x6C\x69\x63\x65"};
unsigned char bob[3] = {"\x42\x6F\x62"};

unsigned char ra[32] = {"\x00\x00\x58\x79\xDD\x1D\x51\xE1\x75\x94\x6F\x23\xB1\xB4\x1E\x93\xBA\x31\xC5\x84\xAE\x59\xA4\x26\xEC\x10\x46\xA4\xD0\x3B\x06\xC8"};

unsigned char rb[32] = {"\x00\x01\x8B\x98\xC4\x4B\xEF\x9F\x85\x37\xFB\x7D\x07\x1B\x2C\x92\x8B\x3B\xC6\x5B\xD3\xD6\x9E\x1E\xEE\x21\x35\x64\x90\x56\x34\xFE"};

time_t start,end;
int res;

unsigned char *gg;

unsigned char AS1[32];
unsigned char AS2[32];

unsigned char BS1[32];
unsigned char BS2[32];
unsigned char BSK[16];

//============独立验证时用到的参数==========
unsigned char x2[32] = {"\x13\x2d\x39\x44\x38\x7b\x63\x1e\xe4\xb0\x55\x89\x9f\x6c\xfe\x42\x8f\xb9\xfc\x9f\xa2\x75\x68\x9f\xeb\x36\xbe\x2b\x60\x21\xea\xbe"};
unsigned char y1[32] = {"\x07\x81\x20\x17\xdb\x06\x91\xd3\x43\x11\x36\x83\x21\x19\xe0\xe1\x94\x4e\x85\x5a\xed\xfc\xa7\x10\xed\xd1\x46\x6e\x69\x01\x8e\xa1"};
unsigned char y2[32] = {"\x89\xf9\xf0\x0f\x5e\x05\x10\x6c\xb3\x4f\x60\x0f\xd9\x48\x92\x4b\x87\x24\x7b\xde\x11\xdf\x34\x01\x3d\xb6\xb9\x54\xbb\xf1\x9a\x55"};

unsigned char h[32] = {"\xa1\xc3\xa6\xce\x30\x90\xea\x0d\xbd\x07\xe2\x1b\xcb\xdb\x43\x40\x4b\x80\x98\xf1\x90\x4d\xd6\xe7\x28\x3c\x7d\xfc\xdb\x23\x65\x91"};
unsigned char ys[32] = {"\x51\x2b\x48\xf2\xae\xde\x4b\x10\xef\x25\xca\x58\x46\x49\x93\x8b\xfc\xd6\x3e\xe8\xb4\x8f\xbb\x86\xeb\x82\xa8\x22\x42\x97\x63\x14"};

//如下可以使用SM9 第五部分 指定的曲线类型和主密钥初始化系统
//也可以使用自定义曲线
//
SM9_Init(0,0,32,NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );

// ========================================================
SM9_MSK msk = SM9_MSK_New(32, cks);  // 申明一个签名主密钥
SM9_MSPK mspk = SM9_MSPK_New(32);   //申明一个主签名公钥

SM9_GenMSignPubKey(&msk, &mspk);  // 生成签名主公钥

gg = SM9_Set_Sign(mspk.x1, mspk.x2, mspk.y1, mspk.y2, NULL); // 启动签名lib

if (gg == NULL){
printf("init sign lib error\n");
return 1;
}
SM9_PK pk = SM9_PK_New(5, id);       // 申明一个签名公钥
SM9_SSK sk = SM9_SSK_New(32);            // 申明一个签名私钥

SM9_GenSignSecKey(&sk, &pk, &msk); // 由公钥（id）生成签名私钥

SM9_Sign sign = SM9_Sign_New(32);   // 申明一个签名体

//===============signature test===============
//使用私钥sk和随机数ran，对消息mes签名
time(&start);

for(int i=0;i<TEST;i++){
SM9_Signature(msg, 20, rand, &sk, &sign);
}
time(&end);

printf("sign %d time is %ld sec\n",TEST, end-start);

time(&start);
for(int i=0;i<TEST;i++){// 验证函数
res = SM9_Verify(msg, 20, &sign, &pk, NULL);
if (res) printf("verify error at %d = %d\n", i,res);
}

time(&end);
printf("verify %d time is %ld sec\n",TEST, end-start);

//===============independent verify test===============
SM9_Free();  //注销SM9

//重新启动SM9
SM9_Init(0,0,32,NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );

SM9_MSPK inmspk = SM9_MSPK_New(32);
SM9_PK inpk = SM9_PK_New(5, id);

inmspk.secLevel =32;
inmspk.x1 = x1;
inmspk.x2 = x2;
inmspk.y1 = y1;
inmspk.y2 = y2;

gg = SM9_Set_Sign(inmspk.x1, inmspk.x2, inmspk.y1, inmspk.y2, NULL); // 启动签名lib

if (gg == NULL){
printf("init sign lib error\n");
return 1;
}

insign.h = h;
insign.xs = xs;
insign.ys = ys;
int inres;
inres = SM9_Verify(msg, 20, &insign, &inpk, NULL);
if (inres) {
printf("independent verify error = %d\n",inres);
}else{
printf("independent verify success! \n");
}

//===============encryption test===============
SM9_MSK esk = SM9_MSK_New(32, eks);  // 申明一个加密主密钥
SM9_MCPK mcpk = SM9_MCPK_New(32);   //申明一个主加密公钥
SM9_GenMEncryptPubKey(&esk, &mcpk); // 生成加密主公钥
gg = SM9_Set_Encrypt(mcpk.x, mcpk.y,NULL);  // 启动加密lib
if (gg == NULL){
printf("init encryption lib error\n");
return 1;
}

SM9_PK epk = SM9_PK_New(3, eid);   //申明一个加密公钥
SM9_CSK csk = SM9_CSK_New(32);   //申明一个加密私钥
SM9_GenEncryptSecKey(&csk, &epk, &esk);  // 由公钥（id）生成加密私钥

SM9_Cipher cipher = SM9_Cipher_New(32);

time(&start);
for(int i=0;i<TEST;i++){
SM9_Encrypt(cmsg, 20, KDF_SM4, er, &epk, &cipher);
}
time(&end);
printf("Encrypt %d time is %ld sec\n",TEST, end-start);

time(&start);
for(int i=0;i<TEST;i++){
res = SM9_Decrypt(&epk, KDF_SM4, &csk, &cipher, plain, &plainlen);
if (res) printf("decrypt error code is %d \n", res);
}
time(&end);
printf("Decrypt %d time is %ld sec\n",TEST, end-start);

//===============keyexchange test===============
SM9_MSK ksk = SM9_MSK_New(32, kks);

SM9_MKPK mkpk = SM9_MKPK_New(32);   //申明一个主协商公钥
SM9_GenMKeyExchangePubKey(&ksk, &mkpk); // 生成协商主公钥

gg = SM9_Set_KeyExchange(mkpk.x, mkpk.y,NULL);  // 启动协商lib

if (gg == NULL){
printf("init keyexchange lib error\n");
return 1;
}

SM9_PK  apk = SM9_PK_New(5, alice);

SM9_PK  bpk = SM9_PK_New(3, bob);
SM9_KSK bsk = SM9_KSK_New(32);
SM9_GenKeyExchangeSecKey(&bsk, &bpk, &ksk);

SM9_Send ase = SM9_Send_New(32);
SM9_Send bse = SM9_Send_New(32);

SM9_SendStep(ra, &bpk, &ase);
SM9_SendStep(rb, &apk, &bse);

time(&start);
for(int i=0;i<TEST;i++){
if(SM9_CheckStep(AS1, BS2)) printf("error at step 1\n");
if(SM9_CheckStep(AS2, BS1)) printf("error at step 2\n");
}
time(&end);
printf("key exchange %d time is %ld sec\n", TEST*2,end-start);
printf("end test \n ================== \n");
return 0;
}


GMSSL
sm3命令行：
echo '20201303zyb' | gmssl sm3

OPENSSL
SM4代码

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/err.h"
#include "openssl/evp.h"

/* Before OpenSSL 1.1.1-pre1, we did not have EVP_sm4_ecb() */
#if defined(OPENSSL_VERSION_NUMBER) \
&& OPENSSL_VERSION_NUMBER < 0x10101001L
static const EVP_CIPHER *(*EVP_sm4_ecb)()=EVP_aes_128_ecb;
#endif

typedef struct {
const unsigned char *in_data;
size_t in_data_len;
const unsigned char *in_ivec;
const unsigned char *in_key;
size_t in_key_len;
} test_case_t;

void test_encrypt_with_cipher(const test_case_t *in, const EVP_CIPHER *cipher)
{
unsigned char *out_buf = NULL;
int out_len;
EVP_CIPHER_CTX *ctx;

ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, cipher, NULL, in->in_key, in->in_ivec);

{
And its length must be an integral multiple of the cipher's block size. */
const size_t bs = EVP_CIPHER_block_size(cipher);
if (in->in_data_len % bs != 0)
{
printf("ERROR-1: data length=%d which is not added yet; block size=%d\n", (int) in->in_data_len, (int) bs);
/* Warning: Remember to do some clean-ups */
EVP_CIPHER_CTX_free(ctx);
return;
}
/* Disable the implicit PKCS#7 padding defined in EVP_CIPHER */
}

out_buf = (unsigned char *) malloc(((in->in_data_len>>4)+1) << 4);
out_len = 0;
EVP_EncryptUpdate(ctx, out_buf, &out_len, in->in_data, in->in_data_len);
if (1)
{
printf("Debug: out_len=%d\n", out_len);
}

if (1)
{
}

EVP_CIPHER_CTX_free(ctx);
if (1)
{
int i;
int len;
for (i=0; i<len; i++)
{
printf("%02x ", out_buf[i]);
}
printf("\n");
}

if (out_buf)
{
free(out_buf);
out_buf = NULL;
}
}

void main()
{
int have_sm4 = (OPENSSL_VERSION_NUMBER >= 0x10101001L);
int have_aes = 1;
const unsigned char data[]=
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
unsigned char ivec[EVP_MAX_IV_LENGTH]; ///< IV 向量
const unsigned char key1[16] = ///< key_data, 密钥内容, 至少16字节
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
test_case_t tc;

tc.in_data = data;
tc.in_data_len = sizeof(data);
tc.in_data_is_already_padded = (tc.in_data_len % 16)==0; // Hard coded 16 as the cipher's block size
tc.in_key = key1;
tc.in_key_len = sizeof(key1);
memset(ivec, 0x00, EVP_MAX_IV_LENGTH);
tc.in_ivec = ivec;

#if defined(OPENSSL_NO_SM4)
have_sm4 = 0;
#endif
if (have_sm4)
{
printf("[1]\n");
printf("Debug: EVP_sm4_ecb() test\n");
test_encrypt_with_cipher(&tc, EVP_sm4_ecb());
}
#if defined(OPENSSL_NO_AES)
have_aes = 0;
#endif
if (have_aes)
{
printf("[2]\n");
printf("Debug: EVP_aes_128_ecb() test\n");
test_encrypt_with_cipher(&tc, EVP_aes_128_ecb());
}
}


SM3代码

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
void tDigest(){
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
EVP_MD_CTX *mdctx;
mdctx = EVP_MD_CTX_new();
char msg1[] = "20201303";
char msg2[] = "ZHANGyibo";
EVP_MD_CTX_init(mdctx);
EVP_DigestInit_ex(mdctx, EVP_sm3(), NULL);
EVP_DigestUpdate(mdctx, msg1, strlen(msg1));
EVP_DigestUpdate(mdctx, msg2, strlen(msg2));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);

printf("Debug:Message1%s and Message2%s digest to:\n",msg1, msg2);
for(int i = 0; i<md_len; i++){

printf("0x%02x ", md_value[i]);
}
printf("\n");
}

int main(){

tDigest();
return 0;
}


1.小组贡献排序及依据（每个人的工作量）：
1）、刘谨铭

2）、何忠鑫

3）、张奕博

2.遇到的问题及解决方法

①BABASSL头文件丢失的问题，我找到对应算法库缺失的代码加入静态链接就好了
②gmlib头文件丢失问题，编译时出现问题，这时候修改cmakelist.txt文件，发现make编译出现的问题，这时候修改文件将最后编译的内容改成自己要编译的文件即可。
③tjfoc-gm头文件丢失，这时候用go get从github上把库copy下来就行了
④crypto++头文件丢失，这时候我们采用vs软件重新编译，按着网络上找的攻略就好
⑤mircal头文件丢失，这时候我们修改makefile文件，将其补充完整就行

3.心得体会

posted @ 2022-12-11 21:33  20201327刘谨铭  阅读(6)  评论(0编辑  收藏  举报