AES加密(兼容php,java,objective-c)


这些天开发android,ios的客户端需要与服务端用php开发的api进行数据交互。为了高大上一些决定用aes加密,但是问题就来了,因为aes有好几种模式,每种模式在各种语言下都是差异化的表现方式,探索了许久终于找到合适他们三种语言的的一套方案。

php:
php的代码就比较简单,几行就搞定

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. static $iv = 'AESAPPCLIENT_KEY';//16或16的倍数长个char
  2. //$privateKey是加密 解密需要的密钥
  3. function aesEncode($data,$privateKey){
  4.     $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey$data, MCRYPT_MODE_CBC,$iv);
  5.     return rtrim((base64_encode($encrypted)));
  6. }
  7. function aesDecode($data,$privateKey){
  8.     $encryptedData = base64_decode($data);
  9.     $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey$encryptedData, MCRYPT_MODE_CBC,$iv);
  10.     return rtrim($decrypted);
  11. }

加密后末尾莫名多了些东东 就用rtrim()去掉了

java:
主要注意要补零

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public class ToolsUtils {
  2. private final static String IVKEY = "AESAPPCLIENT_KEY";
  3. public static String encrypt(String data,String key) {
  4.     try {
  5.         Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
  6.         int blockSize = cipher.getBlockSize();
  7.         SecretKeySpec keyspec = new SecretKeySpec(fullZore(key,blockSize), "AES");
  8.         IvParameterSpec ivspec = new IvParameterSpec(fullZore(IVKEY,blockSize));
  9.         cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
  10.         byte[] encrypted = cipher.doFinal(fullZore(data,blockSize));
  11.         return new String(Base64.encode(encrypted, Base64.DEFAULT)).trim();
  12.     } catch (Exception e) {
  13.         e.printStackTrace();
  14.         return "";
  15.     }
  16. }
  17. public static String decrypt(String data,String key) {
  18.     try {
  19.         Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
  20.         int blockSize = cipher.getBlockSize();
  21.         SecretKeySpec keyspec = new SecretKeySpec(fullZore(key,blockSize), "AES");
  22.         IvParameterSpec ivspec = new IvParameterSpec(fullZore(IVKEY,blockSize));
  23.         cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
  24.         byte[] decrypted = cipher.doFinal(Base64. decode(data, Base64.DEFAULT));
  25.         return new String(decrypted).trim();
  26.     } catch (Exception e) {
  27.         e.printStackTrace();
  28.         return "";
  29.     }
  30. }
  31. public static byte[] fullZore(String data,int blockSize){
  32.     byte[] dataBytes = data.getBytes();
  33.     int plaintextLength = dataBytes.length;
  34.     if (plaintextLength % blockSize != 0) {
  35.         plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
  36.     }
  37.     byte[] plaintext = new byte[plaintextLength];
  38.     System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
  39.     return plaintext;
  40. }
  41. }

objective-c:
也是主要注意要补零
NSData+AES.h

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #import <Foundation/Foundation.h>
  2. #import <CommonCrypto/CommonCryptor.h>
  3. @interface NSData (AES)
  4. - (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv;
  5. - (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv;
  6. - (NSString *)base64Encoding;
  7. + (id)dataWithBase64EncodedString:(NSString *)string;
  8. @end

NSData+AES.m

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #import "NSData+AES.h"
  2. static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3. @implementation NSData (AES)
  4. - (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv
  5. {
  6.     char keyPtr[kCCKeySizeAES128+1];
  7.     bzero(keyPtr, sizeof(keyPtr));
  8.     [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
  9.     char ivPtr[kCCKeySizeAES128+1];
  10.     bzero(ivPtr, sizeof(ivPtr));
  11.     [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
  12.     NSUInteger dataLength = [self length];
  13.     int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
  14.     int newSize = 0;
  15.     if(diff > 0)
  16.     {
  17.         newSize = dataLength + diff;
  18.     }
  19.     char dataPtr[newSize];
  20.     memcpy(dataPtr, [self bytes], [self length]);
  21.     for(int i = 0; i < diff; i++)
  22.     {
  23.         dataPtr[i + dataLength] = 0x00;
  24.     }
  25.     size_t bufferSize = newSize + kCCBlockSizeAES128;
  26.     void *buffer = malloc(bufferSize);
  27.     size_t numBytesEncrypted = 0;
  28.     CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
  29.                                           kCCAlgorithmAES128,
  30.                                           0x00, //No padding
  31.                                           keyPtr,
  32.                                           kCCKeySizeAES128,
  33.                                           ivPtr,
  34.                                           dataPtr,
  35.                                           sizeof(dataPtr),
  36.                                           buffer,
  37.                                           bufferSize,
  38.                                           &numBytesEncrypted);
  39.     if(cryptStatus == kCCSuccess)
  40.     {
  41.         return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
  42.     }
  43.     return nil;
  44. }
  45. - (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv
  46. {
  47.     char keyPtr[kCCKeySizeAES128+1];
  48.     bzero(keyPtr, sizeof(keyPtr));
  49.     [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
  50.     char ivPtr[kCCKeySizeAES128+1];
  51.     bzero(ivPtr, sizeof(ivPtr));
  52.     [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
  53.     NSUInteger dataLength = [self length];
  54.     size_t bufferSize = dataLength + kCCBlockSizeAES128;
  55.     void *buffer = malloc(bufferSize);
  56.     size_t numBytesEncrypted = 0;
  57.     CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
  58.                                           kCCAlgorithmAES128,
  59.                                           0x00, //No padding
  60.                                           keyPtr,
  61.                                           kCCKeySizeAES128,
  62.                                           ivPtr,
  63.                                           [self bytes],
  64.                                           dataLength,
  65.                                           buffer,
  66.                                           bufferSize,
  67.                                           &numBytesEncrypted);
  68.     if(cryptStatus == kCCSuccess)
  69.     {
  70.         return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
  71.     }
  72.     return nil;
  73. }
  74. + (id)dataWithBase64EncodedString:(NSString *)string;
  75. {
  76.     if (string == nil)
  77.         [NSException raise:NSInvalidArgumentException format:nil];
  78.     if ([string length] == 0)
  79.         return [NSData data];
  80.     static char *decodingTable = NULL;
  81.     if (decodingTable == NULL)
  82.     {
  83.         decodingTable = malloc(256);
  84.         if (decodingTable == NULL)
  85.             return nil;
  86.         memset(decodingTable, CHAR_MAX, 256);
  87.         NSUInteger i;
  88.         for (i = 0; i < 64; i++)
  89.             decodingTable[(short)encodingTable[i]] = i;
  90.     }
  91.     const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
  92.     if (characters == NULL) // Not an ASCII string!
  93.         return nil;
  94.     char *bytes = malloc((([string length] + 3) / 4) * 3);
  95.     if (bytes == NULL)
  96.         return nil;
  97.     NSUInteger length = 0;
  98.     NSUInteger i = 0;
  99.     while (YES)
  100.     {
  101.         char buffer[4];
  102.         short bufferLength;
  103.         for (bufferLength = 0; bufferLength < 4; i++)
  104.         {
  105.             if (characters[i] == '\0')
  106.                 break;
  107.             if (isspace(characters[i]) || characters[i] == '=')
  108.                 continue;
  109.             buffer[bufferLength] = decodingTable[(short)characters[i]];
  110.             if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
  111.             {
  112.                 free(bytes);
  113.                 return nil;
  114.             }
  115.         }
  116.         if (bufferLength == 0)
  117.             break;
  118.         if (bufferLength == 1) // At least two characters are needed to produce one byte!
  119.         {
  120.             free(bytes);
  121.             return nil;
  122.         }
  123.         // Decode the characters in the buffer to bytes.
  124.         bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
  125.         if (bufferLength > 2)
  126.             bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
  127.         if (bufferLength > 3)
  128.             bytes[length++] = (buffer[2] << 6) | buffer[3];
  129.     }
  130.     bytes = realloc(bytes, length);
  131.     return [NSData dataWithBytesNoCopy:bytes length:length];
  132. }
  133. - (NSString *)base64Encoding
  134. {
  135.     if ([self length] == 0)
  136.         return @"";
  137.     char *characters = malloc((([self length] + 2) / 3) * 4);
  138.     if (characters == NULL)
  139.         return nil;
  140.     NSUInteger length = 0;
  141.     NSUInteger i = 0;
  142.     while (i < [self length])
  143.     {
  144.         char buffer[3] = {0,0,0};
  145.         short bufferLength = 0;
  146.         while (bufferLength < 3 && i < [self length]) buffer[bufferLength++] = ((char *)[self bytes])[i++]; // Encode the bytes in the buffer to four characters, including padding “=” characters if necessary. 
  147.         characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
  148.         characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
  149.         if (bufferLength > 1)
  150.             characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
  151.         else characters[length++] = '=';
  152.         if (bufferLength > 2)
  153.             characters[length++] = encodingTable[buffer[2] & 0x3F];
  154.         else characters[length++] = '=';
  155.     }
  156.     return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSUTF8StringEncoding freeWhenDone:YES];
  157. }
  158. @end

ios测试代码 code:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. NSString *textData = @"this is text";
  2.     NSString *iv = @"1234567890123456";//must be 16 or 16*i length
  3.     NSString *key = @"key";
  4.     NSData *encodeData =  [[textData dataUsingEncoding:NSUTF8StringEncoding] AES128EncryptWithKey:key iv:iv];
  5.     NSLog(@"encode data:%@",[encodeData base64Encoding]);// print base64 code
  6.     NSData *decodeData = [encodeData AES128DecryptWithKey:key iv:iv];
  7.     NSLog(@"decode data:%@",[[NSString alloc] initWithData:decodeData encoding:NSUTF8StringEncoding]);

声明:大家学-卢卫湘|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - AES加密(兼容php,java,objective-c)


加vx: beyonds 备注:app上架 lwxshow