前几天项目用到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

  





sm4加密 解密(oc)的更多相关文章

  1. SM4加密算法实现Java和C#相互加密解密

    SM4加密算法实现Java和C#相互加密解密 近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多 ...

  2. Cryptopp iOS 使用 RSA加密解密和签名验证签名

    Cryptopp 是一个c++写的功能完善的密码学工具,类似于openssl 官网:https://www.cryptopp.com 以下主要演示Cryptopp 在iOS上的RSA加密解密签名与验证 ...

  3. 手摸手带你认识https涉及的知识,并实现https加密解密,加签解签

    目录 http访问流程 https访问流程 证书 加密/解密 加签/验签 Java实现https 拓展 @ 看完整的代码,直接去完整代码实现,看实现完后会遇到的坑,直接去测试过程中的问题,包括经过代理 ...

  4. Python常用加密解密算法

    MD5加密 简介 这是一种使用非常广泛的加密方式,不可逆的,常见16位和32位一般都是md5 实现 import hashlib data = '你好' print(hashlib.md5(data. ...

  5. PHP的学习--RSA加密解密

    PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...

  6. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

    Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

  7. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

    场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

  8. php使用openssl进行Rsa长数据加密(117)解密(128) 和 DES 加密解密

    PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文:解密的时候需要128个字符解密一下,然后拼接成数据. 加 ...

  9. c#和js互通的AES加密解密

    一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...

随机推荐

  1. radio值未出现JQ获取值问题

    $('input:radio[name="modelExtend.manageType"]:checked').val(); 选中的获取的值不是空或者null而是on

  2. [NOIP2014]寻找道路(图论)

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  3. Ret2Libc 练习(2) -- VirtualProtect

    这几天做了NSCTF和GCTF,耽误了几天,今天继续. 这次绕过DEP的方法是利用VirtualProtect函数将shellcode所在的内存属性改成可执行状态就可以绕过DEP了. 首先看一下Vir ...

  4. java 自动登录代码

    javaBean的代码    package bean;    import java.io.Serializable;    public class Admin implements Serial ...

  5. python字符串基础知识

    1.python字符串可以用"aaa",'aaa',"""aaa""这三种方式来表示 2.python中的转义字符串为" ...

  6. ubuntu系统lamp环境搭建、数据库迁移、设置数据库外部访问

    sudo passwd root设置两次密码su输入设置的密码exit (退出root帐号) 1.sudo apt-get update 2.sudo apt-get install apache2 ...

  7. node express 304 avoid

    method 1 Why do I need this? The right answer is: I don’t need that trick! The example below is just ...

  8. c#变量缺少using引用,如何快速加上using,加Using的快捷键[bubuko.com]

    在vs的“工具”->“选项”中,左侧树形菜单,“环境”下的“键盘”中设置快捷键. 在“显示命令包含”输入框内输入“显示智能标记”,找到“视图.显示智能标记”,可以看到该命令的快捷键已经分配了2个 ...

  9. 01从c到c++

    c++的发展历史  + 80年代贝尔实验室 本贾尼 + 83年 正式命名c++ + 87年 gnu制定了c++标准 + 92年 微软和IBM分别制定了c++标准 + 98年 ansi ISO 制定了标 ...

  10. asp.net中如何防止用户重复点击提交按钮

    asp.net中如何防止用户重复点击提交按钮   asp.net 中防止因为网速慢等影响交互的问题导致用户可能点击多次提交按钮,从而导致数据库中出现多条重复的记录,经过亲自验证在网上找的方法,找到两个 ...