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,不固定,

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

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

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

先上ios端的代码:

  1 &nbsp;<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, 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]!='' )
 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, 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*)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 char *tmpStr=[decoded UTF8String];
160     int i=0;
161     
162     while( tmpStr[i]!='' )
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这个函数为了把解码后的字符串,末尾去掉''

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

 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 ?>
原文地址:https://www.cnblogs.com/luojianqun/p/4401467.html