IOS 与 PHP 通信加密,使用AES 128 CBC no padding
这个网上的资料真实浩如烟海,但是真正有价值的屈指可数
自己尝试了一天多,终于还是搞定了。
再次要感谢网上的前辈么。
比如下面这个关于php和java端的实现:
http://my.oschina.net/Jacker/blog/86383
关于php和java端的实现。
再比如下面这个关于ios端的实现:
http://www.cnblogs.com/wanyakun/p/3403352.html
为何要采用 no padding 这种形式:
AES加密如果原输入数据不够16字节的整数位,就要补齐,如果采用
pkcs7或者pkcs5这种加密方式,末端添加的数据可能是0x1,0x2,0x3,不固定,
在解码后需要把末端多余的字符去掉,就显得比较棘手。
如果不管补齐多少位,末端都是'\0',去掉的话比较容易操作。
好了,再次确认一下,这里使用的是 AES128 CBC no padding加密解密方式。
先上ios端的代码:
- <pre class="objc" name="code">//
- // AES128.m
- // login
- //
- // Created by wangdan on 15-3-3.
- // Copyright (c) 2015年 wangdan. All rights reserved.
- //
- #import "AES128.h"
- #import <CommonCrypto/CommonCryptor.h>
- #import "GTMBase64.h"
- @implementation AES128
- +(NSString *)AES128Encrypt:(NSString *)plainText withKey:(NSString *)key
- {
- if( ![self validKey:key] ){
- return nil;
- }
- char keyPtr[kCCKeySizeAES128+];
- memset(keyPtr, , sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- char ivPtr[kCCBlockSizeAES128+];
- memset(ivPtr, , sizeof(ivPtr));
- [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
- NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
- NSUInteger dataLength = [data length];
- int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
- unsigned long newSize = ;
- if(diff > )
- {
- newSize = dataLength + diff;
- NSLog(@"diff is %d",diff);
- }
- char dataPtr[newSize];
- memcpy(dataPtr, [data bytes], [data length]);
- for(int i = ; i < diff; i++)
- {
- dataPtr[i + dataLength] =0x0000;
- }
- size_t bufferSize = newSize + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- memset(buffer, , bufferSize);
- size_t numBytesCrypted = ;
- CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
- kCCAlgorithmAES128,
- 0x0000,
- [key UTF8String],
- kCCKeySizeAES128,
- [key UTF8String],
- dataPtr,
- sizeof(dataPtr),
- buffer,
- bufferSize,
- &numBytesCrypted);
- if (cryptStatus == kCCSuccess) {
- NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
- return [GTMBase64 stringByEncodingData:resultData];
- }
- free(buffer);
- return nil;
- }
- +(NSString *)processDecodedString:(NSString *)decoded
- {
- if( decoded==nil || decoded.length== ){
- return nil;
- }
- const char *tmpStr=[decoded UTF8String];
- int i=;
- while( tmpStr[i]!='\0' )
- {
- i++;
- }
- NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding];
- return final;
- }
- +(NSString *)AES128Decrypt:(NSString *)encryptText withKey:(NSString *)key
- {
- if( ![self validKey:key] ){
- return nil;
- }
- char keyPtr[kCCKeySizeAES128 + ];
- memset(keyPtr, , sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- char ivPtr[kCCBlockSizeAES128 + ];
- memset(ivPtr, , sizeof(ivPtr));
- [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
- NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
- NSUInteger dataLength = [data length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- size_t numBytesCrypted = ;
- CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
- kCCAlgorithmAES128,
- 0x0000,
- [key UTF8String],
- kCCBlockSizeAES128,
- [key UTF8String],
- [data bytes],
- dataLength,
- buffer,
- bufferSize,
- &numBytesCrypted);
- if (cryptStatus == kCCSuccess) {
- NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
- NSString *decoded=[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
- return [self processDecodedString:decoded];
- }
- free(buffer);
- return nil;
- }
- +(BOOL)validKey:(NSString*)key
- {
- if( key==nil || key.length != ){
- return NO;
- }
- return YES;
- }
- -(NSString *)processDecodedString:(NSString *)decoded
- {
- if( decoded==nil || decoded.length== ){
- return nil;
- }
- const char *tmpStr=[decoded UTF8String];
- int i=;
- while( tmpStr[i]!='\0' )
- {
- i++;
- }
- NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding];
- return final;
- }
- @end
上述代码需要说明的是,进行AES编码时,输入编码必须是16字节的整数倍,不然调用ios 的系统api会报错 -4003
补齐的字节数全部填充为0
另外 processDecodedString这个函数为了把解码后的字符串,末尾去掉'\0'
下面是PHP端的代码,这个代码是大神些写的啊,经过实际实验是能使用的:
- <?php
- $privateKey = "1234567812345678";
- $iv = "1234567812345678";
- $data = "Test String";
- //加密
- $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv);
- echo(base64_encode($encrypted));
- echo '<br/>';
- //解密
- $encryptedData = base64_decode("2fbwW9+8vPId2/foafZq6Q==");
- $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, $encryptedData, MCRYPT_MODE_CBC, $iv);
- echo($decrypted);
- ?>
IOS 与 PHP 通信加密,使用AES 128 CBC no padding的更多相关文章
- javascript 与 PHP 通信加密,使用AES 128 CBC no padding,以及ios,java,c#文章例子
运行环境 php7.0 不适用于 php7.0以上版本,因为mcrypt_encrypt()函数已删除 为何要采用 no padding 这种形式: AES加密如果原输入数据不够16字节的整数位,就要 ...
- [加密]在AES的CBC模式下 pydes vs crypto
因为项目中有个非常重要的功能,并发量和访问量都很大,里面使用了pydes,总感觉它的性能不太好,从别人的对比来看,性能差距应该挺大,但还是自己测试下吧. 自己测试,心里更有数. 环境 macos 10 ...
- iOS CommonCrypto 对称加密 AES ecb,cbc
CommonCrypto 为苹果提供的系统加密接口,支持iOS 和 mac 开发: 不仅限于AES加密,提供的接口还支持其他DES,3DES,RC4,BLOWFISH等算法, 本文章主要讨论AES在i ...
- iOS加密之AES
心急的童鞋直接看这里Demo 运行之后可以去在线加密网站验证 AES(Advanced Encryption Standard)高级加密标准,又称Rijndael加密法,是美国联邦政府采用的一种区块加 ...
- aes 128、192、256位,cbc、cfb、ecb、ofb、pcbc加密解密
AES加解密总共有以下这些 算法/模式/填充 字节加密后数据长度 不满16字节加密后长度 AES/CBC/NoPadding 16 不支持 AES/CBC/PKCS5Padding 32 16 AES ...
- java对称加密(AES)
java对称加密(AES) 博客分类: Java javaAES对称加密 /** * AESHelper.java * cn.com.songjy.test * * Function: TODO * ...
- javascript AES加密 C#AES解密实现
首先需要引入js类库 crypto-js(开源),地址:http://code.google.com/p/crypto-js 现在很多人无法打开这个地址不要紧,下面我们会将全部代码贴出来 需要引入 a ...
- 使用python进行加密解密AES算法
使用python进行加密解密AES算法-代码分享-PYTHON开发者社区-pythoner.org 使用python进行加密解密AES算法 TY 发布于 2011-09-26 21:36:53,分类: ...
- iOS,Android,.NET通用AES加密算法
原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...
随机推荐
- MIT-6.824 MapReduce
概述 MapReduce是由JeffreyDean提出的一种处理大数据的编程模型,用户定义map和reduce函数,map函数处理原始数据生成一系列键值对中间数据,reduce函数并合相同key的键值 ...
- 高可用Kubernetes集群-14. 部署Kubernetes集群性能监控平台
参考文档: Github介绍:https://github.com/kubernetes/heapster Github yaml文件: https://github.com/kubernetes/h ...
- nginx反向代理tomcat应用,struts2网站程序redirect时导致请求地址错误的解决方法
一个使用struts2的网站在登录页面需要进行redirect跳转,大致如下: <package name="admin" extends="httl-defaul ...
- Python进阶量化交易场外篇3——最大回撤评价策略风险
新年伊始,很荣幸笔者的<教你用 Python 进阶量化交易>专栏在慕课专栏板块上线了,欢迎大家订阅!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外会陆续推出一些手记来辅助同学们学习 ...
- 1.AKATSUKI
## 1.AKATSUKI - “晓”,日本漫画<火影忍者>及其衍生作品中的一个秘密组织. - 成立之初是为了给自己的国家带来和平. ## 2.团队成员 - 邱东宝 - 211606325 ...
- ns3的输入输出奥秘(二) 命令行参数
命令行参数 (1) UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); echoClient.SetAttribute (&q ...
- Python 访问soap服务
使用库:subs soap服务信息: 网址:http://mobile.bjmemc.com.cn/AirService/Service.asmx 功能:使用其中的GetData服务获取北京各个地点的 ...
- 【Leetcode】81. Search in Rotated Sorted Array II
Question: Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? ...
- Helm 安装 wordpress
1. 前置需要安装 storageclass 然后 安装helm 客户端 helm tiller 服务端 2. 设置 当前的位阿里云的 repo 3. 查找 wordpress的镜像 helm sea ...
- Jquery Cookie操作
// 写入 $.cookie('the_cookie','the_value');// 读取 $.cookie('the_cookie');// 删除 $.cookie('the_cookie',nu ...