这个网上的资料真实浩如烟海,但是真正有价值的屈指可数
自己尝试了一天多,终于还是搞定了。
再次要感谢网上的前辈么。
比如下面这个关于php和java端的实现:
关于php和java端的实现。
再比如下面这个关于ios端的实现:
为何要采用 no padding 这种形式:
aes加密如果原输入数据不够16字节的整数位,就要补齐,如果采用
pkcs7或者pkcs5这种加密方式,末端添加的数据可能是0x1,0x2,0x3,不固定,
在解码后需要把末端多余的字符去掉,就显得比较棘手。
如果不管补齐多少位,末端都是'\0',去掉的话比较容易操作。
好了,再次确认一下,这里使用的是 aes128 cbc no padding加密解密方式。
先上ios端的代码:
//// aes128.m// login//// created by wangdan on 15-3-3.// copyright (c) 2015年 wangdan. all rights reserved.//#import aes128.h#import #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]!='\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 + 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]!='\0' ) { i++; } nsstring *final=[[nsstring alloc]initwithbytes:tmpstr length:i encoding:nsutf8stringencoding]; return final; }@end
上述代码需要说明的是,进行aes编码时,输入编码必须是16字节的整数倍,不然调用ios 的系统api会报错 -4003
补齐的字节数全部填充为0
另外 processdecodedstring这个函数为了把解码后的字符串,末尾去掉'\0'
下面是php端的代码,这个代码是大神些写的啊,经过实际实验是能使用的: