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端的代码:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.  <pre class="objc" name="code">//  
  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 <CommonCrypto/CommonCryptor.h>  
  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, 0sizeof(keyPtr));  
  28.     [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
  29.       
  30.       
  31.     char ivPtr[kCCBlockSizeAES128+1];  
  32.     memset(ivPtr, 0sizeof(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.     voidvoid *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 charchar *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 *)key  
  101. {  
  102.       
  103.     if( ![self validKey:key] ){  
  104.         return nil;  
  105.     }  
  106.       
  107.     char keyPtr[kCCKeySizeAES128 + 1];  
  108.     memset(keyPtr, 0sizeof(keyPtr));  
  109.     [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
  110.       
  111.     char ivPtr[kCCBlockSizeAES128 + 1];  
  112.     memset(ivPtr, 0sizeof(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.     voidvoid *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*)key  
  145. {  
  146.     if( key==nil || key.length !=16 ){  
  147.         return NO;  
  148.     }  
  149.     return YES;  
  150. }  
  151.   
  152.   
  153.   
  154. -(NSString *)processDecodedString:(NSString *)decoded  
  155. {  
  156.     if( decoded==nil || decoded.length==0 ){  
  157.         return nil;  
  158.     }  
  159.     const charchar *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端的代码,这个代码是大神些写的啊,经过实际实验是能使用的:

[php]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?php  
  2. $privateKey = "1234567812345678";  
  3. $iv     = "1234567812345678";  
  4. $data   = "Test String";  
  5.    
  6. //加密  
  7. $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey$data, MCRYPT_MODE_CBC, $iv);  
  8. echo(base64_encode($encrypted));  
  9. echo '<br/>';  
  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. ?>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值