查看: 76|回复: 0

[Reverse] 深入浅出国密SMx

[复制链接]

22

主题

23

帖子

0

精华

VIP

Rank: 16

学币
10
荣耀
0
rank
0
违规
0

VIP

    发表于 2020-6-15 01:02:17 | 显示全部楼层 |阅读模式

    前言  来看看国密-。-
    基本介绍  以下内容主要参考自 https://blog.csdn.net/andylau00j/article/details/54427395
      SMx密钥长度和分组长度均为128位。
    SM1  SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
    SM2  SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
      SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高。
    SM3  SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
      SM3杂凑算法是我国自主设计的密码杂凑算法,适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。为了保证杂凑算法的安全性,其产生的杂凑值的长度不应太短,例如MD5输出128比特杂凑值,输出长度太短,影响其安全性SHA-1算法的输出长度为160比特,SM3算法的输出长度为256比特,因此SM3算法的安全性要高于MD5算法和SHA-1算法。
    SM4  SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
    SM4分组密码算法是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。要保证一个对称密码算法的安全性的基本条件是其具备足够的密钥长度,SM4算法与AES算法具有相同的密钥长度分组长度128比特,因此在安全性上高于3DES算法。
    SM4算法描述
      SM2是椭圆曲线公钥密码算法,自己能力有限不好说明。
    SM3是类似于MD5的消息摘要,也不好展开。
    唯一能展开便是SM4了,不过不要紧我在网上收集了一些可用的代码,如果>大家感兴趣可以自行研究。
      SM4分组密码算法是一个迭代分组密码算法,由加解密算法和密钥扩展算法组成。SM4分组密码算法采用非平衡Feistel结构,分组长度和密钥长度均为128bit。加密算法与密钥拓展算法均采用非线性迭代结构。加密运算和解密运算的算法结构相同,解密运算的轮密钥的使用顺序与加密运算相反。
      加密过程主要由32次迭代和1次反序变换R组成。
      算法结构图图下:

    深入浅出国密SMx

    深入浅出国密SMx
    IDA跟踪  IDA载入

    深入浅出国密SMx

    深入浅出国密SMx
      整个程序分为三步
    • 设置密钥
    • sm4加密
    • 输出加密结果
      先查看sm4_setkey_enc函数

    深入浅出国密SMx

    深入浅出国密SMx

    深入浅出国密SMx

    深入浅出国密SMx
      不用关心怎么运算的。
      可以看到种子密钥在这里

    深入浅出国密SMx

    深入浅出国密SMx
      最后产生了32个32位的子密钥
      截图有点乱

    深入浅出国密SMx

    深入浅出国密SMx
      我们知道SM4是由32次迭代运算组成的,并且以128位作为分组长度
      将明文进行分组

    深入浅出国密SMx

    深入浅出国密SMx
      对128位的明文分为4块

    深入浅出国密SMx

    深入浅出国密SMx
      而后进行32轮迭代

    深入浅出国密SMx

    深入浅出国密SMx
      最后进行反序

    深入浅出国密SMx

    深入浅出国密SMx
      然后将结果输出

    深入浅出国密SMx

    深入浅出国密SMx
      以上所用到的代码如下:
    #include <string.h>
    
    #include <stdio.h>
    
    #include "sm4.h"
    
    int main()
    
    {
    
    unsigned char key[16] = {0xDA,0x98,0xF1,0xDA,0x31,0x2A,0xB7,0x53,0xA5,0x70,0x3A,0x0B,0xFD,0x29,0x0D,0xD6};
    
    unsigned char input[16] = {0x66,0x6c,0x61,0x67,0x7b,0x65,0x34,0x34,0x33,0x35,0x33,0x34,0x31,0x2d,0x34,0x30};
    
    unsigned char output[16]={0xc7,0xbc,0xa4,0xf4,0xac,0x18,0x62,0x39,0xca,0xd1,0xcb,0x2d,0x79,0x7c,0x14,0xc3};
    
    unsigned char input2[16] = {0xc7,0xbc,0xa4,0xf4,0xac,0x18,0x62,0x39,0xca,0xd1,0xcb,0x2d,0x79,0x7c,0x14,0xc3};
    
    unsigned char output2[16] = {0};
    
    unsigned char iv[]={'\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00'};
    
    sm4_context ctx;
    
    unsigned long i;
    
    //encrypt standard testing vector
    
    printf("----encrypt testing----\n");
    
    sm4_setkey_enc(&ctx,key);
    
    sm4_crypt_ecb(&ctx,1,16,input,output);
    
    for(i=0;i<16;i++)
    
    printf("%02x ", output[i]);
    
    printf("\n");
    
    //decrypt testing
    
    printf("----decrypt testing----\n");
    
    sm4_setkey_dec(&ctx,key);
    
    sm4_crypt_ecb(&ctx,0,16,output,output);
    
    for(i=0;i<16;i++)
    
    printf("%02x ", output[i]);
    
    printf("\n");
    
    return 0;
    
    }
      更多的代码会添加到附件中
    有关SMx的代码Python  有人写了一个关于smx的python库,并且其中提供了示例代码。
      gmssl官网
      这里贴上sm4的例子
    from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
    
    key = b'3l5butlj26hvv313'
    value = b'111'
    iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    crypt_sm4 = CryptSM4()
    
    crypt_sm4.set_key(key, SM4_ENCRYPT)
    encrypt_value = crypt_sm4.crypt_ecb(value)
    crypt_sm4.set_key(key, SM4_DECRYPT)
    decrypt_value = crypt_sm4.crypt_ecb(encrypt_value)
    assert value == decrypt_value
    
    crypt_sm4.set_key(key, SM4_ENCRYPT)
    encrypt_value = crypt_sm4.crypt_cbc(iv , value)
    crypt_sm4.set_key(key, SM4_DECRYPT)
    decrypt_value = crypt_sm4.crypt_cbc(iv , encrypt_value)
    assert value == decrypt_value
    print("Ok!")
    Csm2  由于使用到了opensll库因此安装以及编译命令如下:
    sudo apt-get install libssl
    sudo apt-get install openssl
    
    gcc sm2.c sm2test.c -o sm2-test -lssl -lcrypto
    sm3  编译的命令gcc sm3.c sm3test.c -o  sm3-test
    sm4  编译的命令gcc sm4.c sm4test.c -o sm4-test
      代码会作为附件上传
    总结  至此基本上常见的算法都已经涉及到了,这个假期也过的很充实。
      很期待下一次的总结。

    游客,如果您要查看本帖隐藏内容请回复

    温馨提示:
    1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
    2.回复帖子不仅是对作者的最好奖励,还可以获得学币奖励,请尊重作者的劳动成果,拒绝做伸手党!
    3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
    学逆向论坛-免费的逆向学习论坛
    微信公众号
    快速回复 返回顶部 返回列表