zoukankan      html  css  js  c++  java
  • 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 ?>
  • 相关阅读:
    组件传值---组件与弹窗组件传值
    elementUI拿到当前表格行的数据的另一种写法
    elementUi-复选框,使用v-for循环出来的复选框,默认多个值为勾选状态
    点击事件,根据不同的下标实现切换不同的内容
    elementUI表格行的点击事件,点击表格,拿到当前行的数据
    在使用element-ui搭建的表格中,实现点击"定位"按钮后,屏幕滚动到对应行的位置
    renren-fast-vue-动态路由-添加路由-方式一(直接在原有结构上添加)
    renren-fast-vue-动态路由
    vue-element-admin打包后白屏的问题
    2月20日-寒假学习进度20
  • 原文地址:https://www.cnblogs.com/luojianqun/p/4401467.html
Copyright © 2011-2022 走看看