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("\n");
    
    unsigned char* c_str = Hex2Str(output,new_length);
    printf("%s\n", 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] = '\0';
        }
    }
    printf("\n");
    free(input);
//    free(output);
    return output;
}

  

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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM