程序员人生 网站导航

IOS 与 PHP 通信加密,使用AES 128 CBC no padding

栏目:综合技术时间:2015-04-08 08:49:02

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

自己尝试了1天多,终究还是弄定了。

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

比以下面这个关于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,不固定,

在解码后需要把末端过剩的字符去掉,就显得比较辣手。

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

 

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

先上ios真个代码:

 <pre class="objc" name="code">// // AES128.m // login // // Created by wangdan on 15⑶⑶. // 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+1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128+1]; memset(ivPtr, 0, 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 = 0; if(diff > 0) { newSize = dataLength + diff; NSLog(@"diff is %d",diff); } char dataPtr[newSize]; memcpy(dataPtr, [data bytes], [data length]); for(int i = 0; i < diff; i++) { dataPtr[i + dataLength] =0x0000; } size_t bufferSize = newSize + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); memset(buffer, 0, bufferSize); size_t numBytesCrypted = 0; 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==0 ){ return nil; } const char *tmpStr=[decoded UTF8String]; int i=0; while( tmpStr[i]!='' ) { 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 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, 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 = 0; 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 !=16 ){ return NO; } return YES; } -(NSString *)processDecodedString:(NSString *)decoded { if( decoded==nil || decoded.length==0 ){ return nil; } const char *tmpStr=[decoded UTF8String]; int i=0; while( tmpStr[i]!='' ) { i++; } NSString *final=[[NSString alloc]initWithBytes:tmpStr length:i encoding:NSUTF8StringEncoding]; return final; } @end



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

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

 

另外  processDecodedString这个函数为了把解码后的字符串,末尾去掉温@良@顺温@良@顺

 

下面是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); ?>


 

 

 

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐