【无标题】

在 Ubuntu或openEuler中(推荐 openEuler)中调试运⾏教材提供的源代码,⾄少运⾏SM2,SM3,SM4代码,使⽤GmSSL命令验证你代码的正确性,使⽤Markdown记录详细记录实践过程,每完成⼀项功能或者⼀个函数git commit ⼀次。(15分)
SM2
云班课下载的代码在虚拟机上无法编译成功,经过比对发现该代码与上一次实验2-1的代码基本一致,只有函数名不同。所以直接采用上一次代码进行测试。课本上的代码涉及加密解密、签名验签的自测,结果如下:

自检均通过

$ ./sm2_test
Messagse:656e6372797074696f6e207374616e64617264
Cipher:04ebfc718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa
M:656e6372797074696f6e207374616e64617264
SM2_enc_selftest pass
SM2_enc_selftest:0
message:6d65737361676520646967657374
Signature:f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa
SM2_sign_selftest pass
SM2_sign_selftest:0
验证
from gmssl import sm2

Define the keys and message

std_priKey = bytes([
0x39, 0x45, 0x20, 0x8F, 0x7B, 0x21, 0x44, 0xB1, 0x3F, 0x36, 0xE3, 0x8A,
0xC6, 0xD3, 0x9F, 0x95, 0x88, 0x93, 0x93, 0x69, 0x28, 0x60, 0xB5, 0x1A,
0x42, 0xFB, 0x81, 0xEF, 0x4D, 0xF7, 0xC5, 0xB8
])

std_pubKey = bytes([
0x09, 0xF9, 0xDF, 0x31, 0x1E, 0x54, 0x21, 0xA1, 0x50, 0xDD, 0x7D, 0x16,
0x1E, 0x4B, 0xC5, 0xC6, 0x72, 0x17, 0x9F, 0xAD, 0x18, 0x33, 0xFC, 0x07,
0x6B, 0xB0, 0x8F, 0xF3, 0x56, 0xF3, 0x50, 0x20, 0xCC, 0xEA, 0x49, 0x0C,
0xE2, 0x67, 0x75, 0xA5, 0x2D, 0xC6, 0xEA, 0x71, 0x8C, 0xC1, 0xAA, 0x60,
0x0A, 0xED, 0x05, 0xFB, 0xF3, 0x5E, 0x08, 0x4A, 0x66, 0x32, 0xF6, 0x07,
0x2D, 0xA9, 0xAD, 0x13
])

std_Message = bytes([
0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,
0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64
])
print(bytes([0x04, 0xEB, 0xFC, 0x71, 0x8E, 0x8D, 0x17, 0x98, 0x62, 0x04, 0x32, 0x26, 0x8E, 0x77, 0xFE, 0xB6,
0x41, 0x5E, 0x2E, 0xDE, 0x0E, 0x07, 0x3C, 0x0F, 0x4F, 0x64, 0x0E, 0xCD, 0x2E, 0x14, 0x9A, 0x73,
0xE8, 0x58, 0xF9, 0xD8, 0x1E, 0x54, 0x30, 0xA5, 0x7B, 0x36, 0xDA, 0xAB, 0x8F, 0x95, 0x0A, 0x3C,
0x64, 0xE6, 0xEE, 0x6A, 0x63, 0x09, 0x4D, 0x99, 0x28, 0x3A, 0xFF, 0x76, 0x7E, 0x12, 0x4D, 0xF0,
0x59, 0x98, 0x3C, 0x18, 0xF8, 0x09, 0xE2, 0x62, 0x92, 0x3C, 0x53, 0xAE, 0xC2, 0x95, 0xD3, 0x03,
0x83, 0xB5, 0x4E, 0x39, 0xD6, 0x09, 0xD1, 0x60, 0xAF, 0xCB, 0x19, 0x08, 0xD0, 0xBD, 0x87, 0x66,
0x21, 0x88, 0x6C, 0xA9, 0x89, 0xCA, 0x9C, 0x7D, 0x58, 0x08, 0x73, 0x07, 0xCA, 0x93, 0x09, 0x2D,
0x65, 0x1E, 0xFA]).hex())

Initialize the SM2 object

sm2_crypt = sm2.CryptSM2(public_key=std_pubKey.hex(), private_key=std_priKey.hex())

Encrypt the message

encrypted_message = sm2_crypt.encrypt(std_Message)
print(encrypted_message.hex())
由于需要使用固定的随机数,所以需要修改库文件中的代码。 下面为修改后的gmssl库中的python代码

def encrypt(self, data):
    # 加密函数,data消息(bytes)
    msg = data.hex()  # 消息转化为16进制字符串
    # k = func.random_hex(self.para_len)
    k = bytes([0x59, 0x27, 0x6E, 0x27, 0xD5, 0x06, 0x86, 0x1A, 0x16, 0x68, 0x0F, 0x3A, 0xD9, 0xC0, 0x2D, 0xCC,
	0xEF, 0x3C, 0xC1, 0xFA, 0x3C, 0xDB, 0xE4, 0xCE, 0x6D, 0x54, 0xB8, 0x0D, 0xEA, 0xC1, 0xBC, 0x21]).hex()
    C1 = self._kg(int(k, 16), self.ecc_table['g'])
    xy = self._kg(int(k, 16), self.public_key)
    x2 = xy[0:self.para_len]
    y2 = xy[self.para_len:2*self.para_len]
    ml = len(msg)
    t = sm3.sm3_kdf(xy.encode('utf8'), ml/2)
    if int(t, 16) == 0:
        return None
    else:
        form = '%%0%dx' % ml
        C2 = form % (int(msg, 16) ^ int(t, 16))
        C3 = sm3.sm3_hash([
            i for i in bytes.fromhex('%s%s%s' % (x2, msg, y2))
        ])
        if self.mode:
            return bytes.fromhex('%s%s%s' % (C1, C3, C2))
        else:
            return bytes.fromhex('%s%s%s' % (C1, C2, C3))

结果为:

C:\Users\He-Zh\AppData\Local\Programs\Python\Python312\python.exe D:\misc\Attachment\Crypto\SM2.py
04ebfc718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa
04ebfc718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df021886ca989ca9c7d58087307ca93092d651efa59983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd8766
进程已结束,退出代码为 0
可以发现,两个结果不一样,这是因为SM2mode的问题,sm2模式会导致输出的结果顺序不一样。

SM2加密的结果由C1、C2、C3三部分组成,其中C1是生成随机数的计算出的椭圆曲线点,C2是密文数据,C3是SM3的摘要值。不同的实现可能有不同的排列顺序。

第一个结果为C代码中的标准结果,第二个结果为python代码验证的结果,下面将其分解为三部分:

第一个结果:
04ebfc718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df0
59983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd8766
21886ca989ca9c7d58087307ca93092d651efa
第二个结果:
04ebfc718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df0
21886ca989ca9c7d58087307ca93092d651efa
59983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd8766

两个结果后两部分顺序颠倒了
所以SM2加密验证成功

SM2签名

from gmssl import sm2, func

private_key = bytes([0x39, 0x45, 0x20, 0x8f, 0x7b, 0x21, 0x44, 0xb1, 0x3f, 0x36, 0xe3, 0x8a, 0xc6, 0xd3, 0x9f, 0x95,
0x88, 0x93, 0x93, 0x69, 0x28, 0x60, 0xb5, 0x1a, 0x42, 0xfb, 0x81, 0xef, 0x4d, 0xf7, 0xc5,
0xb8]).hex()
public_key = bytes([0x09, 0xf9, 0xdf, 0x31, 0x1e, 0x54, 0x21, 0xa1, 0x50, 0xdd, 0x7d, 0x16, 0x1e, 0x4b, 0xc5, 0xc6,
0x72, 0x17, 0x9f, 0xad, 0x18, 0x33, 0xfc, 0x07, 0x6b, 0xb0, 0x8f, 0xf3, 0x56, 0xf3, 0x50, 0x20,
0xcc, 0xea, 0x49, 0x0c, 0xe2, 0x67, 0x75, 0xa5, 0x2d, 0xc6, 0xea, 0x71, 0x8c, 0xc1, 0xaa, 0x60,
0x0a, 0xed, 0x05, 0xfb, 0xf3, 0x5e, 0x08, 0x4a, 0x66, 0x32, 0xf6, 0x07, 0x2d, 0xa9, 0xad,
0x13]).hex()

sm2_crypt = sm2.CryptSM2(
public_key=public_key, private_key=private_key)
data = b"message digest" # bytes类型
random_hex_str = bytes([0x59, 0x27, 0x6E, 0x27, 0xD5, 0x06, 0x86, 0x1A, 0x16, 0x68, 0x0F, 0x3A, 0xD9, 0xC0, 0x2D, 0xCC,
0xEF, 0x3C, 0xC1, 0xFA, 0x3C, 0xDB, 0xE4, 0xCE, 0x6D, 0x54, 0xB8, 0x0D, 0xEA, 0xC1, 0xBC,
0x21]).hex()
sign = sm2_crypt.sign(data, random_hex_str) # 16进制
print(sign)
print(‘f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa’)
C:\Users\He-Zh\AppData\Local\Programs\Python\Python312\python.exe D:\misc\Attachment\Crypto\SM2.py
04ebfc718e8d1798620432268e77feb6415e9c43817a9d76b4847336957a0de711c0a451ba212c7061f513d1c8963402575d8ca8f06cdea4a554083e8e6458f6
f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa
公私钥、消息、随机数均一致,签名结果不同,原因未知。

SM3
一段式和三段式实现SM3

$ pwd
/home/zhanhe/rodec/bestidiocs2024/ch03/sm3
$ gcc -o sm31 sm31.c
$ gcc -o sm33 sm33.c
$ ./sm31
消息:abc
Hash结果:
len=32
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
$ ./sm33
消息:abcd
Hash结果:
82ec580fe6d36ae4f81cae3c73f4a5b3b5a09c943172dc9053c69fd8e18dca1e
Openssl实现SM3

$ pwd
/home/zhanhe/rodec/bestidiocs2024/ch03/sm3/sm3openssl
$ ./test
Raw data (sample1): abc
Hash length: 32 bytes.
Hash value:
66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0

Raw data (sample2):
0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64 0x61 0x62 0x63 0x64
Hash length: 32 bytes.
Hash value:
debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732
HMAC-SM3

$ pwd
/home/zhanhe/rodec/bestidiocs2024/ch03/sm3/hmac-sm3
$ ls
Makefile sm3.c sm3.h test.c
$ make
gcc -Wall -O2 -o test test.c sm3.c
$ ./test
Message: abc
HMAC: ec76c401 b2ddceb3 916bdffa 0469b85f 90536ffc f4ecac77 539f3d8b 8bbe046c
验证
$ echo -n “abcd” | gmssl sm3
82ec580fe6d36ae4f81cae3c73f4a5b3b5a09c943172dc9053c69fd8e18dca1e
$ echo -n “abc” | gmssl sm3
66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
$ echo -ne “\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64\x61\x62\x63\x64” | gmssl sm3
debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732
与代码结果一致

key为"123456"
hex为313233343536
hmac需要对密钥进行预处理,得到16字节的密钥,即长度为32的hex字符串
填充得到31323334353600000000000000000000
$ echo -n “abc” | gmssl sm3hmac -key 31323334353600000000000000000000
ec76c401b2ddceb3916bdffa0469b85f90536ffcf4ecac77539f3d8b8bbe046c
hmac计算结果一致

SM4
16字节的SM4

$ pwd
/home/zhanhe/rodec/bestidiocs2024/ch03/sm4/sm416
$ ./testsm416
明文 (十六进制): 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
密文 (十六进制): 68 1E DF 34 D2 06 96 5E 86 B3 E9 4F 53 6E 42 46
解密后的明文 (十六进制): 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
sm4(16 Bytes ok!)
4个模式的SM4

$ pwd
/home/zhanhe/rodec/bestidiocs2024/ch03/sm4/sm4mode
$ ./test
ecb enc(len=16) memcmp ok
ecb dec(len=16) memcmp ok
ecb enc/dec(len=32) memcmp ok
ecb enc/dec(len=64) memcmp ok
ecb enc/dec(len=128) memcmp ok
ecb enc/dec(len=256) memcmp ok
ecb enc/dec(len=512) memcmp ok
ecb enc/dec(len=1024) memcmp ok
ecb enc/dec(len=2048) memcmp ok
ecb enc/dec(len=4096) memcmp ok
cbc enc(len=32) memcmp ok
cbc dec(len=32) memcmp ok
cbc enc/dec(len=32) memcmp ok
cbc enc/dec(len=64) memcmp ok
cbc enc/dec(len=128) memcmp ok
cbc enc/dec(len=256) memcmp ok
cbc enc/dec(len=512) memcmp ok
cbc enc/dec(len=1024) memcmp ok
cbc enc/dec(len=2048) memcmp ok
cbc enc/dec(len=4096) memcmp ok
cfb enc/dec(len=16) memcmp ok
cfb enc/dec(len=32) memcmp ok
cfb enc/dec(len=64) memcmp ok
cfb enc/dec(len=128) memcmp ok
cfb enc/dec(len=256) memcmp ok
cfb enc/dec(len=512) memcmp ok
cfb enc/dec(len=1024) memcmp ok
cfb enc/dec(len=2048) memcmp ok
cfb enc/dec(len=4096) memcmp ok
ofb enc/dec(len=16) memcmp ok
ofb enc/dec(len=32) memcmp ok
ofb enc/dec(len=64) memcmp ok
ofb enc/dec(len=128) memcmp ok
ofb enc/dec(len=256) memcmp ok
ofb enc/dec(len=512) memcmp ok
ofb enc/dec(len=1024) memcmp ok
ofb enc/dec(len=2048) memcmp ok
ofb enc/dec(len=4096) memcmp ok
验证
16字节的SM4

//查看代码得到密钥和明文
unsigned char key[16] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
unsigned char plain[16] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
unsigned char iv[16] = {
0xeb, 0xee, 0xc5, 0x68,
0x58, 0xe6, 0x04, 0xd8,
0x32, 0x7b, 0x9b, 0x3c,
0x10, 0xc9, 0x0c, 0xa7
};
$ echo -ne “\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10” > key.bin
$ echo -ne “\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10” > plain.txt
$ echo -ne “\xeb\xee\xc5\x68\x58\xe6\x04\xd8\x32\x7b\x9b\x3c\x10\xc9\x0c\xa
7” > iv.bin
$ gmssl sm4_ecb -encrypt -key $(xxd -p -c 32 key.bin) -in plain.txt -out enc.bin

$ od -tc -tx1 enc.bin
0000000 h 036 337 4 322 006 226 ^ 206 263 351 O S n B F
68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46
0000020
$ gmssl sm4_cbc -encrypt -key $(xxd -p -c 32 key.bin) -iv $(xxd -p -c 32 iv.bin) -in plain.txt -out cbc.bin
$ od -tx1 cbc.bin
0000000 3f 1e 73 c3 df d5 a1 32 88 2f e6 9d 99 6c de 93
0000020 82 3f 40 e0 01 d1 54 84 c1 32 ec 05 53 b4 e5 95
0000040
ecb(16字节)、cbc模式结果一致

cfb、ofb代码中并没有给出密文结果

在密标委⽹站http://www.gmbz.org.cn/main/bzlb.html查找SM2,SM3,SM4相关标准,分析代码实现与标准的对应关系。(10分)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值