国密算法SM2/3/4实现

原创
2016/11/24 10:22
阅读数 8.5K

相关信息

国家密码管理局发布的标准

开源实现

简单介绍

SM2

这个就是椭圆加密算法,只是选择了不同的参数。因此用其他一直椭圆曲线的算法实现,通过修改相关方程的参数,也可以实现SM2。关于椭圆曲线的具体算法,可以参考zmworm大神的文章,不过我还是没看懂。

http://www.pediy.com/kssd/pediy06/pediy6014.htm

SM3

这个是类似MD5,SHA256的摘要算法。通过一系列的位运算来获得一个256bit的大数。

SM4

对称加密算法,没仔细看,直接拿源码来用了。跟一般的加密算法用起来没啥区别,一个key既可以加密,也可以解密。

测试

直接上结果吧,最后的测试通过的情况是这样:

  • SM2: 参考GmSSL的实现,直接利用OpenSSL里面的函数设定曲线的参数实现
  • SM3: 直接使用pygmcrypto源码
  • SM4: 直接使用pygmcrypto源码

测试代码: SM4

#include <string.h>
#include <stdio.h>
#include "sm4.h"

int main()
{
    unsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
    unsigned char input[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
    unsigned char output[16];
    sm4_context ctx;
    unsigned long i;

    printf("Key: ");
    for(i=0;i<16;i++)
        printf("%02x ", key[i]);
    printf("\n");
    //encrypt standard testing vector
    sm4_setkey_enc(&ctx,key);
    sm4_crypt_ecb(&ctx,1,16,input,output);
    printf("Encrypted: ");
    for(i=0;i<16;i++)
        printf("%02x ", output[i]);
    printf("\n");

    //decrypt testing
    sm4_setkey_dec(&ctx,key);
    sm4_crypt_ecb(&ctx,0,16,output,output);
    printf("Decrypted: ");
    for(i=0;i<16;i++)
        printf("%02x ", output[i]);
    printf("\n");


    return 0;
}

SM3

#include <string.h>
#include <stdio.h>
#include "sm3.h"

int main( int argc, char *argv[] )
{
        unsigned char *input = "ab";
        int ilen = 2;
        unsigned char output[32];
        int i;
        sm3_context ctx;

        printf("Message:\n");
        printf("%s\n",input);

        sm3(input, ilen, output);
        printf("Hash:\n   ");
        for(i=0; i<32; i++)
        {
                printf("%02x",output[i]);
                if (((i+1) % 4 ) == 0) printf(" ");
        }
        printf("\n");

        printf("Message:\n");
        for(i=0; i < 16; i++)
                printf("abcd");
        printf("\n");

        sm3_starts( &ctx );
        for(i=0; i < 16; i++)
                sm3_update( &ctx, "abcd", 4 );
        sm3_finish( &ctx, output );
        memset( &ctx, 0, sizeof( sm3_context ) );

        printf("Hash:\n   ");
        for(i=0; i<32; i++)
        {
                printf("%02x",output[i]);
                if (((i+1) % 4 ) == 0) printf(" ");
        }
        printf("\n");
    //getch();  //VS2008
}

展开阅读全文
ECC
打赏
1
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
1
分享
返回顶部
顶部