iOS基于openssl 的AES-128-cbc-pkcs5 加解密
来源:互联网 发布:仿站长之家网站源码 编辑:程序博客网 时间:2024/05/16 17:33
前段时间自己写客户端加密解密,查了不少资料。现在把自己写的过程记录下来,分享出去让没写过 openssl aes 的小伙伴少闹点心
闲话不说进入正题
1.AES加密和DES加密的区别这里就不提了,网上好多解释
2.AES加密的方式有很多 128 256 cbc ecb cfb 等等,这里介绍AES-128-cbc-pkcs5 加解密
你可以写一个公共的加密类 也可以给系统类写一个类的扩展 category
因为我的是给接口参数进行加密 所以我的就给NSString写了一个类扩展,如果你自己要写可根据自己情况写(比如给NSData写一个类扩展)
当时写AES的时候因为好长时间不碰C了,所以开辟空间和初始化的时候经常出问题,还有就是加密解密都是单线程的,所以加上了线程锁
解密的时候,最后不要忘了去除填充
好了不多说了直接上代码
4.AES-128-cbc-pkcs5 加密
-(NSString*)encryptAES:(NSString*)key{ @synchronized (self) { const char *Source; unsigned char *InputData=NULL; unsigned char *EncryptData=NULL; char *DecryptData=NULL; unsigned char Key[AES_BLOCK_SIZE+1];//建议用unsigned char unsigned char iv[17] = "****************";//加密的初始化向量,加密解密要一样就行 因为CBC 是循环加密方式 所以这个地方的加密向量一定要和解密端商量好 AES_KEY AesKey; int DataLen=0,SetDataLen=0; NSData *dat = [self dataUsingEncoding:NSUTF8StringEncoding]; Source = [self cStringUsingEncoding:NSUTF8StringEncoding];//要加密的数据 /** ------------ warning warning warning warning ---------------- *strlen()计算的是char* 的长度,但是如果输入中间包括'\0'字符的话, *那么只会加密'\0'前面啊的一段,所以这个strlen()在这个地方来计算加密解密长度 欠妥, *故 以'\0'来判断字符串长度,不符合,这个地方暂时以NSData 的 length 来记录数据长度 * ------------ warning warning warning warning ---------------- */ DataLen = dat.length; memset(Key, 0x00, sizeof(Key)); memcpy(Key, [key cStringUsingEncoding:NSUTF8StringEncoding], AES_BLOCK_SIZE); // set the encryption length SetDataLen = 0; if ((DataLen%AES_BLOCK_SIZE) == 0) { SetDataLen = DataLen + AES_BLOCK_SIZE; } else { SetDataLen = ((DataLen/AES_BLOCK_SIZE)+1) * AES_BLOCK_SIZE; } printf("SetDataLen:%d...\n", SetDataLen);//取16的倍数 InputData = (unsigned char *)malloc(SetDataLen + 1); memset(InputData, 0, SetDataLen + 1);//注意要SetDataLen+1 if(InputData == NULL) { fprintf(stderr, "Unable to allocate memory for InputData\n"); exit(-1); } //计算填充数字 int nNumber; if (DataLen % 16 > 0) nNumber = SetDataLen - DataLen; else nNumber = 16; //填充,PKCS5填充的规则 如果加密数据余16大于0 将余数填充到加密数据后面凑成待加密数据长度正好是16的整数倍,如果加密数据余16正好等于0,那么在加密数据后面填充16个16 memset(InputData, nNumber, SetDataLen); //拷贝资源 memcpy(InputData, Source, DataLen); //开辟加密后的数据空间 EncryptData = (unsigned char *)malloc(SetDataLen+1); if(EncryptData == NULL)//注意要SetDataLen+1 { fprintf(stderr, "Unable to allocate memory for EncryptData\n"); exit(-1); } memset(EncryptData, 0, SetDataLen+1); //设置加密密钥 memset(&AesKey, 0x00, sizeof(AES_KEY)); if(AES_set_encrypt_key(Key, 128, &AesKey) < 0) { fprintf(stderr, "Unable to set encryption key in AES...\n"); exit(-1); } //加密 AES_cbc_encrypt((unsigned char *)InputData, (unsigned char *)EncryptData, SetDataLen, &AesKey, iv, AES_ENCRYPT); //将加密后的数据转成NSData NSData *result = [NSData dataWithBytes:EncryptData length:SetDataLen]; //释放内存 if(InputData != NULL) { free(InputData); InputData = NULL; } if(EncryptData != NULL) { free(EncryptData); EncryptData = NULL; } if(DecryptData != NULL) { free(DecryptData); DecryptData = NULL; } //返回base64编码字符串 使用的GTMBase64 如果你不用这个 可以替换成泥自己的Base64编码方式 return [GTMBase64 stringByEncodingData:result]; } }
5.AES-128-cbc-pkcs5解密
-(NSString*)decryptAESData:(NSString*)key{ @synchronized (self) { const char *Source; char *InputData=NULL; char *EncryptData=NULL; char *DecryptData=NULL; unsigned char Key[AES_BLOCK_SIZE+1];//建议用unsigned char unsigned char iv[17] = <span style="font-family: Arial, Helvetica, sans-serif;">"****************"</span>;//加密的初始化向量,加密解密要一样就行 AES_KEY AesKey; int DataLen=0,SetDataLen=0, i; NSData *da = [GTMBase64 decodeString:self]; Source = [[GTMBase64 decodeString:self] bytes];//[self cStringUsingEncoding:NSUTF8StringEncoding];//要解密的数据 DataLen = da.length; memset(Key, 0x00, sizeof(Key)); memcpy(Key, [key cStringUsingEncoding:NSUTF8StringEncoding], AES_BLOCK_SIZE); // set the encryption length SetDataLen = 0; if ((DataLen%AES_BLOCK_SIZE) == 0) { SetDataLen = DataLen; } else { SetDataLen = ((DataLen/AES_BLOCK_SIZE)+1) * AES_BLOCK_SIZE; } if(AES_set_decrypt_key(Key, 128, &AesKey) < 0) {//设置解密密钥 fprintf(stderr, "Unable to set encryption key in AES...\n"); exit(-1); } DecryptData = (char *)calloc(SetDataLen + 16, sizeof(char)); //解密 AES_cbc_encrypt((unsigned char *)Source, (unsigned char *)DecryptData, SetDataLen, &AesKey, iv, AES_DECRYPT); NSData *result = [NSData dataWithBytes:DecryptData length:SetDataLen]; if(InputData != NULL) { free(InputData); InputData = NULL; } if(EncryptData != NULL) { free(EncryptData); EncryptData = NULL; } if(DecryptData != NULL) { free(DecryptData); DecryptData = NULL; } NSString *backStr = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];// NSLog(@"%@",backStr); //因为加密的时候进行了填充,所以在这个地方需要去除填充 int c = (int)[backStr characterAtIndex:backStr.length - 1]; NSString *sss = [backStr substringToIndex:backStr.length - c]; NSLog(@"%@",sss); return sss; } }好了 差不多 AES-128-cbc-pkcs5 加密解密都在上面了
0 0
- iOS基于openssl 的AES-128-cbc-pkcs5 加解密
- 使用PHP7.1的openssl加解密AES-128-CBC,与7.0之前的版本匹配
- 基于openssl的AES加解密 android
- Openssl中AES加解密——CBC模式
- 利用openssl里的库函数进行AES的加解密—cbc
- AES/CBC/PKCS5Padding加解密
- 使用OpenSSL库的AES加解密
- C++ 和 java 使用 AES CBC 128 加解密
- 【AES】使用OpenSSL库的AES加解密
- C# AES-256-CBC 加解密
- AES CBC和CTR加解密实例
- AES CBC和CTR加解密实例
- AES/CBC/PKCS5Padding 对称算法加解密
- openssl aes 高级加解密
- iOS-AES加解密
- OpenSSL提供了AES加解密算法的API
- 基于openssl的RSA加解密实现
- 基于OpenSSL库的加解密实验
- Android webview与js交互上传图片
- 高维网络 (dp+组合数)
- Java流
- java面试准备-day02
- Android 5.0+新控件学习地址
- iOS基于openssl 的AES-128-cbc-pkcs5 加解密
- axis2 webservice下实现AXIOM service的完整步骤
- ubuntu 16.04 上安装OpenStack Mitaka (all-in-one):Neutron 安装与配置
- 【腾讯Bugly干货分享】Android进程保活招式大全
- JavaMail发送
- 数据类型范围
- Ubuntu-C++环境设置
- HDOJ 1159 Common Subsequence【模板题】
- 对方是否