zoukankan      html  css  js  c++  java
  • sm4加密 解密(oc)

    前几天项目用到sm4加密解密,加密为十六进制字符串,再将十六进制字符串解密。网上百度了下,sm4是密钥长度和加密明文加密密文都为16个字节十六进制数据,网上的sm4 c语言算法很容易搜到,笔者刚开始没怎么理解,以为只能对16字节数据进行加密,并且不论是多少字节的数据加密出来都是16字节的。后来看了下源码,应该是加密的数据应该是16字节或者16的整数倍个字节的数据,若不够16倍数字节应该补0x00数据,最后加密出来的数据和输入数据的长度应该一致,即

    密文长度=明文长度 

    而且密钥长度一致,是16字节的。c的代码里面输入输出都是十六进制数据,需要将字符串转为char类型数组,并且保证长度是16整数倍

    +(unsigned char*)hexEnc:(NSString*)strInput{
        NSData* data = [strInput dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger length = data.length;
        NSUInteger plusLength;
        if(length % 16 == 0){
            plusLength = 0;
        }
        else{
            plusLength = 16 - length % 16;
        }
        NSMutableString* new_str = [[NSMutableString alloc] initWithString:strInput];
        for (int i =0;i < plusLength;i++) {
            [new_str appendString:@" "];
        }
        NSUInteger new_length = length+plusLength;
        Uchar *input = (Uchar*)malloc(sizeof(Uchar)*new_length);
        Uchar *output = (Uchar*)malloc(sizeof(Uchar)*new_length);
        Uchar key[16] = KEY;
        const char *utfChar = [new_str UTF8String];
        memset(input, 0, new_length);
        memcpy(input, utfChar, new_length);
        
        sm4_context ctx;
        unsigned long i;
    
        sm4_setkey_enc(&ctx,key);
        sm4_crypt_ecb(&ctx,1,new_length,input,output);
        
        for(i=0;i<new_length;i++)
        printf("%02x ", output[i]);
        printf("
    ");
        
        unsigned char* c_str = Hex2Str(output,new_length);
        printf("%s
    ", c_str);
        
        free(input);
        free(output);
        return c_str;
    }
    

      

    解密时密文是十六进制字符串,需要将字符串先转为int类型数组,再作解密操作,具体代码  

    +(unsigned char*)hexDec:(NSString*)strInput{
        int inputCharSize = strInput.length/2;
        Uchar* input = (Uchar*)malloc(sizeof(Uchar)*inputCharSize);
        Uchar* output = (Uchar*)malloc(sizeof(Uchar)*inputCharSize);
        for (int i = 0; i<inputCharSize; i++) {
            NSString* str = [strInput substringWithRange:NSMakeRange(i*2, 2)];
            NSString* gw = [str substringWithRange:NSMakeRange(0, 1)]
            ;
            NSString* dw = [str substringWithRange:NSMakeRange(1, 1)];
            int n_gw = [HexToStr str2Int:gw];
            int n_dw = [HexToStr str2Int:dw];
            int result = n_gw * 16 + n_dw;
            input[i] = result;
        }
        Uchar key[16] = KEY;
        
        sm4_context ctx;
        sm4_setkey_dec(&ctx,key);
        sm4_crypt_ecb(&ctx,0,inputCharSize,input,output);
        int kgPos = 0;
        for(int i=0;i<inputCharSize;i++){
            printf("%02x ", output[i]);
            if (output[i] == 32) {
                kgPos = i;
                output[i] = '';
            }
        }
        printf("
    ");
        free(input);
    //    free(output);
        return output;
    }
    

      

    demo地址:https://github.com/dinner/sm4

      

  • 相关阅读:
    一条Sql的Spark之旅
    Redis学习笔记:Redis在C#中的使用
    MySQL_表操作
    git上传新项目到coding
    Jenkins 安装 on centos7
    day 36
    表单生成器(Form Builder)之表单数据存储结构mongodb篇
    ORA-16032和ORA-07286 LOG_ARCHIVE_DEST_1没生效
    SQL查询小案例
    mysql从5.6升级到5.7后出现 Expression #1 of ORDER BY clause is not in SELECT list,this is incompatible with DISTINCT
  • 原文地址:https://www.cnblogs.com/symen/p/6085486.html
Copyright © 2011-2022 走看看