博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS 与 PHP 通信加密,使用AES 128 CBC no padding
阅读量:4705 次
发布时间:2019-06-10

本文共 6112 字,大约阅读时间需要 20 分钟。

这个网上的资料真实浩如烟海,但是真正有价值的屈指可数

自己尝试了一天多,终于还是搞定了。

再次要感谢网上的前辈么。

比如下面这个关于php和java端的实现:

关于php和java端的实现。

再比如下面这个关于ios端的实现:

为何要采用 no padding 这种形式:

AES加密如果原输入数据不够16字节的整数位,就要补齐,如果采用

pkcs7或者pkcs5这种加密方式,末端添加的数据可能是0x1,0x2,0x3,不固定,

在解码后需要把末端多余的字符去掉,就显得比较棘手。

如果不管补齐多少位,末端都是'\0',去掉的话比较容易操作。

 

好了,再次确认一下,这里使用的是  AES128 CBC no padding加密解密方式。

先上ios端的代码:

1  
//  2 //  AES128.m  3 //  login  4 //  5 //  Created by wangdan on 15-3-3.  6 //  Copyright (c) 2015年 wangdan. All rights reserved.  7 //  8   9 #import "AES128.h" 10  11 #import 
12 #import "GTMBase64.h" 13 14 15 16 @implementation AES128 17 18 19 +(NSString *)AES128Encrypt:(NSString *)plainText withKey:(NSString *)key 20 { 21 22 if( ![self validKey:key] ){ 23 return nil; 24 } 25 26 char keyPtr[kCCKeySizeAES128+1]; 27 memset(keyPtr, 0, sizeof(keyPtr)); 28 [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 29 30 31 char ivPtr[kCCBlockSizeAES128+1]; 32 memset(ivPtr, 0, sizeof(ivPtr)); 33 [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; 34 35 NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding]; 36 NSUInteger dataLength = [data length]; 37 38 int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128); 39 unsigned long newSize = 0; 40 41 if(diff > 0) 42 { 43 newSize = dataLength + diff; 44 NSLog(@"diff is %d",diff); 45 } 46 47 char dataPtr[newSize]; 48 memcpy(dataPtr, [data bytes], [data length]); 49 for(int i = 0; i < diff; i++) 50 { 51 dataPtr[i + dataLength] =0x0000; 52 } 53 54 size_t bufferSize = newSize + kCCBlockSizeAES128; 55 void *buffer = malloc(bufferSize); 56 memset(buffer, 0, bufferSize); 57 58 size_t numBytesCrypted = 0; 59 60 CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 61 kCCAlgorithmAES128, 62 0x0000, 63 [key UTF8String], 64 kCCKeySizeAES128, 65 [key UTF8String], 66 dataPtr, 67 sizeof(dataPtr), 68 buffer, 69 bufferSize, 70 &numBytesCrypted); 71 72 if (cryptStatus == kCCSuccess) { 73 NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; 74 return [GTMBase64 stringByEncodingData:resultData]; 75 } 76 free(buffer); 77 return nil; 78 } 79 80 81 82 83 +(NSString *)processDecodedString:(NSString *)decoded 84 { 85 if( decoded==nil || decoded.length==0 ){ 86 return nil; 87 } 88 const char *tmpStr=[decoded UTF8String]; 89 int i=0; 90 91 while( tmpStr[i]!='\0' ) 92 { 93 i++; 94 } 95 NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding]; 96 return final; 97 98 } 99 100 +(NSString *)AES128Decrypt:(NSString *)encryptText withKey:(NSString *)key101 {102 103 if( ![self validKey:key] ){104 return nil;105 }106 107 char keyPtr[kCCKeySizeAES128 + 1];108 memset(keyPtr, 0, sizeof(keyPtr));109 [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];110 111 char ivPtr[kCCBlockSizeAES128 + 1];112 memset(ivPtr, 0, sizeof(ivPtr));113 [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];114 115 NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];116 NSUInteger dataLength = [data length];117 size_t bufferSize = dataLength + kCCBlockSizeAES128;118 void *buffer = malloc(bufferSize);119 120 size_t numBytesCrypted = 0;121 CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,122 kCCAlgorithmAES128,123 0x0000,124 [key UTF8String],125 kCCBlockSizeAES128,126 [key UTF8String],127 [data bytes],128 dataLength,129 buffer,130 bufferSize,131 &numBytesCrypted);132 if (cryptStatus == kCCSuccess) {133 NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];134 135 NSString *decoded=[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];136 return [self processDecodedString:decoded];137 }138 139 free(buffer);140 return nil;141 142 }143 144 +(BOOL)validKey:(NSString*)key145 {146 if( key==nil || key.length !=16 ){147 return NO;148 }149 return YES;150 }151 152 153 154 -(NSString *)processDecodedString:(NSString *)decoded155 {156 if( decoded==nil || decoded.length==0 ){157 return nil;158 }159 const char *tmpStr=[decoded UTF8String];160 int i=0;161 162 while( tmpStr[i]!='\0' )163 {164 i++;165 }166 NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding];167 return final;168 169 }170 171 @end

上述代码需要说明的是,进行AES编码时,输入编码必须是16字节的整数倍,不然调用ios 的系统api会报错 -4003

补齐的字节数全部填充为0

 

另外  processDecodedString这个函数为了把解码后的字符串,末尾去掉'\0'

 

下面是PHP端的代码,这个代码是大神些写的啊,经过实际实验是能使用的:

1 
';10 11 //解密12 $encryptedData = base64_decode("2fbwW9+8vPId2/foafZq6Q==");13 $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, $encryptedData, MCRYPT_MODE_CBC, $iv);14 echo($decrypted);15 ?>

 

posted on
2015-04-08 09:02 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/luojianqun/p/4401467.html

你可能感兴趣的文章
python中的内容编码
查看>>
Codefoeces 734F. Anton and School 数学
查看>>
斐波那契查找法
查看>>
java 22 - 23 多线程之定时器的概述和使用例子
查看>>
我们都爱大长腿
查看>>
实验10:Problem G: STL——多重集的插入和删除
查看>>
相邻最大差值
查看>>
WebBrowser 加载网页
查看>>
xcode 8 重新支持插件
查看>>
6-12 SVM小结
查看>>
ABOUTCG发布Maya 刚体特效完全教程
查看>>
单例模式
查看>>
Codeforces Round #485 (Div. 2)
查看>>
数据结构与算法之排序算法的时间复杂度、空间复杂度总结
查看>>
Rabbitmq之高级特性——实现消费端限流&NACK重回队列
查看>>
RANK和BANK
查看>>
js中构造函数和普通函数的区别
查看>>
Linux SD/MMC/SDIO驱动分析
查看>>
2-sat学习笔记
查看>>
Java与算法之(11) - 合并排序
查看>>