2016-05-13 11:41:50 LuohanCC 阅读数 10571
IOS 使用AES/ECB/PKCS7Padding 加密、解密数据

AES:加密方式
ECB:工作方式
PKCS5Padding:填充方式(IOS中只有PKCS7Padding,别担心,PKCS5Padding是PKCS7Padding的一个子集,所以使用PKCS7Padding代替也是一样的)
可能用到的框架:
AESCrypt-ObjC-master - Github:https://github.com/Gurpartap/aescrypt

加密中的补位操作:
加密时,如果长度少于16个字节,需要补满16个字节,补(16-len)个(16-len),例如:@"AAAA"这个节符串是4个字节,16 - 4 =  12,所以需要再补12个十进制的12;解密时,因为加密时补的是十进制1到16,解密时,需要把这部分的补位去掉,逐一判断要解密的字符串,每个字节是不是 char >= 1 && char <=  16,如果是的话,就用0来替换以前的值,直到结束,原理是这样,在IOS中一般不需要我们自己进行补位操作,底层会帮我们完成。

字符编码:
常见的字符编码有:UTF-8、ASCII、Base64、十六进制等等,不要使用UTF-8,加密过程是使用UTF-8完成的,但是加密完后的NSData无法通过UTF-8编码格式转出成NSString,推荐使用Base64编码和十六进制编码,下面举例:

使用Base64编码:(如果不能解密中文请使用十六进制或其他编码)
+ (NSData*)base64DataFromString:(NSString*)string;
+ (NSString*)base64StringFromData:(NSData*)data length:(NSUInteger)length;

使用十六进制编码:(需要注意的是:加、解密过程中是使用UTF-8完成的,在加密时,只需要将加密结果NSData对象转为十六进制字符串,而解密时,也只需要将获取到的16进制字符串转换成NSData然后再进行解密,切记)
NSData*cipher = [XNFunctionconvertHexStrToData:content];
//方法如下(注意:这里的十六进制是指十六进制字符串,不是0x000002)

//十六进制转换为NSData
+ (
NSData*)convertHexStrToData:(NSString*)str {
   
 if (!str || [str length] ==0) {
       
 return nil;
    }
   
   
 NSMutableData *hexData = [[NSMutableDataalloc]initWithCapacity:8];
   
 NSRange range;
   
 if ([str length] %2==0) {
        range =
 NSMakeRange(0,2);
    }
 else {
        range =
 NSMakeRange(0,1);
    }
   
 for (NSIntegeri = range.location; i < [str length]; i +=2) {
       
 unsigned int anInt;
       
 NSString *hexCharStr = [str substringWithRange:range];
       
 NSScanner *scanner = [[NSScanneralloc]initWithString:hexCharStr];
       
        [scanner
 scanHexInt:&anInt];
       
 NSData *entity = [[NSDataalloc]initWithBytes:&anIntlength:1];
        [hexData
 appendData:entity];
       
        range.
location+= range.length;
        range.
length=2;
    }
   NSLog(@"hexdata: %@", hexData);
   
 return hexData;
}

//NSData转换为16进制
+ (
NSString*)convertDataToHexStr:(NSData*)data {
   
 if (!data || [data length] ==0) {
       
 return @"";
    }
   
 NSMutableString *string = [[NSMutableStringalloc]initWithCapacity:[datalength]];
   
    [data
 enumerateByteRangesUsingBlock:^(constvoid*bytes,NSRangebyteRange,BOOL*stop) {
       
 unsigned char *dataBytes = (unsignedchar*)bytes;
       
 for (NSIntegeri =0; i < byteRange.length; i++) {
           
 NSString *hexStr = [NSStringstringWithFormat:@"%x", (dataBytes[i]) & 0xff];
           
 if ([hexStr length] ==2) {
                [string
 appendString:hexStr];
            }
 else {
                [string
 appendFormat:@"0%@", hexStr];
            }
        }
    }];
   
   
 return string;
}

进入正题,我们使用框架加、解密:
NSString*str =@"ABC123!@#中文";
NSString*key =@"F8hfdtgfu**0Ka0";
NSData*password = [[keydataUsingEncoding:NSUTF8StringEncoding]MD5Sum];
CCCryptorStatusstatus =kCCSuccess;
NSData*data = [strdataUsingEncoding:NSUTF8StringEncoding];
//加密
NSData* result = [data dataEncryptedUsingAlgorithm:kCCAlgorithmAES128
                                               key:password
                                           options:kCCOptionPKCS7Padding|kCCOptionECBMode
                                             error:&status];
//解密:
NSData*encrypted = [resultdecryptedDataUsingAlgorithm:kCCAlgorithmAES128
                                                   key:password //字符串key够16位,可以直接传进去,不用转成NSdata也行
                                               options:kCCOptionPKCS7Padding|kCCOptionECBMode
                                                 error:&status];
plainString = [[NSStringalloc]initWithData:encryptedencoding:NSUTF8StringEncoding];
NSLog(@"%@", plainString);  //输出:ABC123!@#中文

问题来了,有时候后台(用Java代码使用十六进制编码加密的)传过来的密文是十六进制的字符串,这时候使用这个框架可能会解不开。正确流程应该是这样的,首先拿到密文后,需要将其转换成NSdata,而IOS中没有提供直接将十六进制字符串转成NSdata的API,所以我找来了两个个工具函数,直接拿来用,在上文中有提到,然后再将这个NSData解密,解密后将结果过按UTF-8编码将其转成NSString,结果为nil,苹果官方文档中提到如果NSData中含有非UTF-8编码时就会返回nil,这里很奇怪,明明已经在拿到密文时就使用函数convertHexStrToData将其转成了NSData(Hex->UTF-8->NSData),却里无法转出NSString。
NSString*plainString =nil;
NSString*key =@"%F8hfdtgfu**0Ka0";
CCCryptorStatusstatus =kCCSuccess;
//十六进制字符串 -> NSData
NSData*data = [selfconvertHexStrToData:text];
//解密:
NSData*encrypted = [datadecryptedDataUsingAlgorithm:kCCAlgorithmAES128
                                                 key:key
                                             options:kCCOptionPKCS7Padding|kCCOptionECBMode
                                               error:&status];
plainString = [selfconvertDataToHexStr:encrypted];  //转出成功,但看起来还是十六进制字符串,于是进行下步
plainString = [selfstringFromHexString:plainString];//十六进制字符串转成普通字符串
NSLog(@"%@", plainString); //失败

+ (NSString*)stringFromHexString:(NSString*)hexString {//
   char*myBuffer = (char*)malloc((int)[hexStringlength] /2+1);
   
 bzero(myBuffer, [hexStringlength] /2+1);
   
 for (inti =0; i < [hexStringlength] -1; i +=2) {
       
 unsigned int anInt;
       
 NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i,2)];
       
 NSScanner * scanner = [[NSScanneralloc]initWithString:hexCharStr];
        [scanner
 scanHexInt:&anInt];
        myBuffer[i /
 2] = (char)anInt;
    }
   
 NSString *unicodeString = [NSStringstringWithCString:myBufferencoding:4];
   
 NSLog(@"字符串:%@",unicodeString);
   return unicodeString; 
}

这找了很久原因,无果,后来在google上看到了另一种加、解密的步骤,直接抠下来用
//16位的key,补位操作省略
NSString*key =@"F8hfdtgfu**0Ka0";
//HexString -> NSData
NSData*cipher = [selfconvertHexStrToData:text];
//解密
NSData*plain  = [cipherAES256DecryptWithKey:key];
//直接是用UTF-8编码转出
NSString*plainString = [[NSStringalloc]initWithData:plainencoding:NSUTF8StringEncoding];
NSLog(@"[解密结果] :%@", plainString); //解密成功

于是我查看了这两个方法的加密步骤,确实有所不同:
AESCrypt-ObjC-master的解密步骤:
1.自动识别参数key和参数iv的类型,如果传入的是NSString,就将其按UTF-8编码转成NSData
2.调用FixKeyLengths将key和iv按 传入的参数algorithm(CCAlgorithm)自动进行补位
3.调用CCCryptorCreate创建一个Cryptorr
/*创建 cryptor
     *
 参数1:解密
     *
 参数2:填充方式,这里传入kCCAlgorithmAES128
     *
 参数3:工作模式:kCCOptionPKCS7Padding | kCCOptionECBMode
     *
 参数4key
     *
 参数5key的长度
     *
 参数6iv
     *参数7CCCryptorRef cryptor = NULL;
*/
CCCryptorCreate(kCCEncrypt, algorithm, options, [keyDatabytes], [keyDatalength], [ivDatabytes], &cryptor );

NSData* resultData = [self_runCryptor: cryptorresult: &status];

4.更新Crypto,最终得到resultData
- (NSData*) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus*) status {
    size_tbufsize = CCCryptorGetOutputLength( cryptor, (size_t)[selflength],true );
    void* buf =malloc( bufsize );
    size_tbufused = 0;
    size_tbytesTotal = 0;
    /*更新 cryptor
       *参数1:cryptor
       *参数2:密文
       *参数3:密文大小
       *参数4buf
       *参数5bufsize
       *参数6...
    */
    *status =CCCryptorUpdate( cryptor, [selfbytes], (size_t)[selflength],buf, bufsize, &bufused );
    if( *status !=kCCSuccess{
       free( buf );
       return( nil );
    }
 
    bytesTotal += bufused;

    // From Brent Royal-Gordon (Twitter: architechies):
    //  Need to update buf ptr past used bytes when calling CCCryptorFinal()
    *status =CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
    if( *status != kCCSuccess ) {
       free( buf );
       return( nil );
    }
 
    bytesTotal += bufused;

    return( [NSDatadataWithBytesNoCopy: buflength: bytesTotal] );
}

另一种解密步骤:(也就是本次需求中遇到的AES/ECB/PKCS5Padding + 16进制编码)
- (NSData*)AES256DecryptWithKey:(NSString*)key  //解密
{
    //AES的密钥长度有128字节、192字节、256字节几种,这里举出可能存在的最大长度
   charkeyPtr[kCCKeySizeAES256+1];
   
 bzero(keyPtr,sizeof(keyPtr));
    [keygetCString:keyPtrmaxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];
    //密文的长度
   NSUIntegerdataLength = [selflength];
    //密文长度+补位长度
   size_tbufferSize = dataLength +kCCBlockSizeAES128;
    //为解密结果开辟空间
   void*buffer =malloc(bufferSize);
   size_t numBytesDecrypted = 0;
    /* kCCDecrypt:解密
     * kCCAlgorithmAES128:加密方式
     * kCCOptionPKCS7Padding | kCCOptionECBMode:工作模式
     * keyPtr:UTF-8格式的key
     * kCCBlockSizeAES128:按16位长度解密
     * iv:AES不用iv
     * [self bayes]:密文
     * ...
     */
   CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,kCCAlgorithmAES128
                                         kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
 kCCBlockSizeAES128,
                                         
 NULL,
                                          [
selfbytes], dataLength,
                                          buffer, bufferSize,
                                          &numBytesDecrypted);
   
 if (cryptStatus == kCCSuccess) {
       
 return [NSDatadataWithBytesNoCopy:bufferlength:numBytesDecrypted];
    }
   
 free(buffer);
   
 return nil;
}

建议使用第二种方式根据不同加密方式和填充方式传入相应的参数即可,其实第一种使用CCCryptor应该也可以,但是不知道为什么在解密十六进制编码时不成功,同样是API/usr/include/CommonCrypto中的API,虽然方法不同,但底层实现应该都是一样的,估计是AESCrypt-ObjC-master框架的问题吧,暂不深究。




2012-10-18 19:57:47 vipa1888 阅读数 8892
    最近忙于android和iOS的项目,写完了android的DES 的ECB模式加密解密(相关连接:http://blog.csdn.net/vipa1888/article/details/8086037),又回到了Ios上面,因为本人也是最近今年开始研究ios的,所以Ios上面好多东西都不懂,进过了半年的研究,终于吧ios的DES 的ECB模式对称加密解密搞定了,本人遇到的问题很严重的问题,网上写的好多16进制数转化位字节都有问题的,经过本人研究发现他们有一个地方写错了,导致解密后的NSString 位null,我的代码已经修复了这个问题,下面贴出源代码供大家参考:


首先贴出加密类的头文件:

//
//  DesUtil.h
//  Author:spring sky
//  QQ:840950105
//  Email:vipa1888@163.com
//

#import <Foundation/Foundation.h>

@interface DesUtil : NSObject
/**
 DES加密
 */
+(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key;

/**
 DES解密
 */
+(NSString *) decryptUseDES:(NSString *)plainText key:(NSString *)key;



@end

加密类的实现类:

//
//  DesUtil.m
//  Author:spring sky
//  QQ:840950105
//  Email:vipa1888@163.com
//

#import "DesUtil.h"
#import <CommonCrypto/CommonCryptor.h>
#import "ConverUtil.h"
@implementation DesUtil


static Byte iv[] = {1,2,3,4,5,6,7,8};
/*
 DES加密
 */
+(NSString *) encryptUseDES:(NSString *)clearText key:(NSString *)key
{
    NSString *ciphertext = nil;
    NSData *textData = [clearText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [clearText length];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                          kCCOptionECBMode,
                                          [key UTF8String], kCCKeySizeDES,
                                          iv,
                                          [textData bytes]	, dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSLog(@"DES加密成功");
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        Byte* bb = (Byte*)[data bytes];
        ciphertext = [ConverUtil parseByteArray2HexString:bb];
    }else{
        NSLog(@"DES加密失败");
    }
    return ciphertext;
}

/**
 DES解密
 */
+(NSString *) decryptUseDES:(NSString *)plainText key:(NSString *)key
{
    NSString *cleartext = nil;
    NSData *textData = [ConverUtil parseHexToByteArray:plainText];
    NSUInteger dataLength = [textData length];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
                                          kCCOptionECBMode,
                                          [key UTF8String], kCCKeySizeDES,
                                          iv,
                                          [textData bytes]	, dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSLog(@"DES解密成功");

        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        cleartext = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }else{
        NSLog(@"DES解密失败");
    }
    return cleartext;
}



@end



下面是转码类,主要是16进制和字节的转化 
头文件:

//
//  ConverUtil.h
//  Author:spring sky
//  QQ:840950105
//  Email:vipa1888@163.com
//

#import <Foundation/Foundation.h>

@interface ConverUtil : NSObject

/**
 64编码
 */
+(NSString *)base64Encoding:(NSData*) text;

/**
 字节转化为16进制数
 */
+(NSString *) parseByte2HexString:(Byte *) bytes;

/**
 字节数组转化16进制数
 */
+(NSString *) parseByteArray2HexString:(Byte[]) bytes;

/*
 将16进制数据转化成NSData 数组
 */
+(NSData*) parseHexToByteArray:(NSString*) hexString;

@end

实现类:

//
//  ConverUtil.m
//  Author:spring sky
//  QQ:840950105
//  Email:vipa1888@163.com
//

#import "ConverUtil.h"

@implementation ConverUtil
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/**
 64编码
 */
+(NSString *)base64Encoding:(NSData*) text
{
    if (text.length == 0)
        return @"";
    
    char *characters = malloc(text.length*3/2);
    
    if (characters == NULL)
        return @"";
    
    int end = text.length - 3;
    int index = 0;
    int charCount = 0;
    int n = 0;
    
    while (index <= end) {
        int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
        | (((int)(((char *)[text bytes])[index + 1]) & 0x0ff) << 8)
        | ((int)(((char *)[text bytes])[index + 2]) & 0x0ff);
        
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = encodingTable[(d >> 6) & 63];
        characters[charCount++] = encodingTable[d & 63];
        
        index += 3;
        
        if(n++ >= 14)
        {
            n = 0;
            characters[charCount++] = ' ';
        }
    }
    
    if(index == text.length - 2)
    {
        int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
        | (((int)(((char *)[text bytes])[index + 1]) & 255) << 8);
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = encodingTable[(d >> 6) & 63];
        characters[charCount++] = '=';
    }
    else if(index == text.length - 1)
    {
        int d = ((int)(((char *)[text bytes])[index]) & 0x0ff) << 16;
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = '=';
        characters[charCount++] = '=';
    }
    NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
    return rtnStr;
}

/**
 字节转化为16进制数
 */
+(NSString *) parseByte2HexString:(Byte *) bytes
{
    NSMutableString *hexStr = [[NSMutableString alloc]init];
    int i = 0;
    if(bytes)
    {
        while (bytes[i] != '\0')
        {
            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
            if([hexByte length]==1)
                [hexStr appendFormat:@"0%@", hexByte];
            else
                [hexStr appendFormat:@"%@", hexByte];
            
            i++;
        }
    }
    NSLog(@"bytes 的16进制数为:%@",hexStr);
    return hexStr;
}


/**
 字节数组转化16进制数
 */
+(NSString *) parseByteArray2HexString:(Byte[]) bytes
{
    NSMutableString *hexStr = [[NSMutableString alloc]init];
    int i = 0;
    if(bytes)
    {
        while (bytes[i] != '\0')
        {
            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
            if([hexByte length]==1)
                [hexStr appendFormat:@"0%@", hexByte];
            else
                [hexStr appendFormat:@"%@", hexByte];
            
            i++;
        }
    }
    NSLog(@"bytes 的16进制数为:%@",hexStr);
    return [hexStr uppercaseString];
}

/*
 将16进制数据转化成NSData 数组
 */
+(NSData*) parseHexToByteArray:(NSString*) hexString
{
    int j=0;
    Byte bytes[hexString.length]; 
    for(int i=0;i<[hexString length];i++)
    {
        int int_ch;  /// 两位16进制数转化后的10进制数
        unichar hex_char1 = [hexString characterAtIndex:i]; ////两位16进制数中的第一位(高位*16)
        int int_ch1;
        if(hex_char1 >= '0' && hex_char1 <='9')
            int_ch1 = (hex_char1-48)*16;   //// 0 的Ascll - 48
        else if(hex_char1 >= 'A' && hex_char1 <='F')
            int_ch1 = (hex_char1-55)*16; //// A 的Ascll - 65
        else
            int_ch1 = (hex_char1-87)*16; //// a 的Ascll - 97
        i++;
        unichar hex_char2 = [hexString characterAtIndex:i]; ///两位16进制数中的第二位(低位)
        int int_ch2;
        if(hex_char2 >= '0' && hex_char2 <='9')
            int_ch2 = (hex_char2-48); //// 0 的Ascll - 48
        else if(hex_char2 >= 'A' && hex_char1 <='F')
            int_ch2 = hex_char2-55; //// A 的Ascll - 65
        else
            int_ch2 = hex_char2-87; //// a 的Ascll - 97
        
        int_ch = int_ch1+int_ch2;
        bytes[j] = int_ch;  ///将转化后的数放入Byte数组里
        j++;
    }

    NSData *newData = [[NSData alloc] initWithBytes:bytes length:hexString.length/2];
    NSLog(@"newData=%@",newData);
    return newData;
}

@end


测试结果:

2012-10-18 19:58:41.592 [3356:707] 明文 = 1PALMPAY   key = 12345678

2012-10-18 19:58:41.599 [3356:707] DES加密成功

2012-10-18 19:58:41.601 [3356:707] bytes 16进制数为:0be9d717b1478b32

2012-10-18 19:58:41.603 [3356:707] 加密后的数据:0BE9D717B1478B32

2012-10-18 19:58:41.604 [3356:707] newData=<0be9d717 b1478b32>

2012-10-18 19:58:41.607 [3356:707] DES解密成功

2012-10-18 19:58:41.608 [3356:707] 解密后的数据:1PALMPAY



本人的工作内容主要是银行金融方面,所以经常会使用到各种的加密解密,如果有需要帮助的朋友可以联系我,如果我能搞定的,一定尽力而已!

欢迎转载,但是必须保留版权!







2015-12-29 14:00:23 ETmanwenhan 阅读数 7268
//////////////AES加密方式: AES 128 ECB PKCS7Padding 16进制加密解密  //////////////
    NSString *originalStr=@"AES";

    //加密
    NSString *encryStr = [AES128Util AES128Encrypt:originalStr key:AES_KEY];
    //解密
    NSString *decryStr = [AES128Util AES128Decrypt:encryStr key:AES_KEY];
    
    NSLog(@"\n加密前:%@\n加密后:%@ \n解密后:%@",originalStr,encryStr,decryStr);


//
//  AES128Util.h
//  ASE128Demo
//
//  Created by zhenghaishu on 11/11/13.
//  Copyright (c) 2013 Youku.com inc. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface AES128Util : NSObject

+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key;

+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key;

@end


//
//  AES128Util.m
//  ASE128Demo
//
//  Created by zhenghaishu on 11/11/13.
//  Copyright (c) 2013 Youku.com inc. All rights reserved.
//

#import "AES128Util.h"
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"

@implementation AES128Util

+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        //return [GTMBase64 stringByEncodingData:resultData];
        return [self hexStringFromData:resultData];

    }
    free(buffer);
    return nil;
}


+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    //NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSData *data=[self dataForHexString:encryptText];
    
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        return [[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] autorelease];
    }
    free(buffer);
    return nil;
}

// 普通字符串转换为十六进
+ (NSString *)hexStringFromData:(NSData *)data {
    Byte *bytes = (Byte *)[data bytes];
    // 下面是Byte 转换为16进制。
    NSString *hexStr = @"";
    for(int i=0; i<[data length]; i++) {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i] & 0xff]; //16进制数
        newHexStr = [newHexStr uppercaseString];
        
        if([newHexStr length] == 1) {
            newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
        }
        
        hexStr = [hexStr stringByAppendingString:newHexStr];
        
    }
    return hexStr;
}

//参考:http://blog.csdn.net/linux_zkf/article/details/17124577
//十六进制转Data
+ (NSData*)dataForHexString:(NSString*)hexString
{
    if (hexString == nil) {
        
        return nil;
    }
    
    const char* ch = [[hexString lowercaseString] cStringUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* data = [NSMutableData data];
    while (*ch) {
        if (*ch == ' ') {
            continue;
        }
        char byte = 0;
        if ('0' <= *ch && *ch <= '9') {
            
            byte = *ch - '0';
        }else if ('a' <= *ch && *ch <= 'f') {
            
            byte = *ch - 'a' + 10;
        }else if ('A' <= *ch && *ch <= 'F') {
            
            byte = *ch - 'A' + 10;
            
        }
        
        ch++;
        
        byte = byte << 4;
        
        if (*ch) {
            
            if ('0' <= *ch && *ch <= '9') {
                
                byte += *ch - '0';
                
            } else if ('a' <= *ch && *ch <= 'f') {
                
                byte += *ch - 'a' + 10;
                
            }else if('A' <= *ch && *ch <= 'F'){
                
                byte += *ch - 'A' + 10;
                
            }
            
            ch++;
            
        }
        
        [data appendBytes:&byte length:1];
        
    }
    
    return data;
}

@end

AES在线加密工具

http://www.seacha.com/tools/aes.html?src=wenhan123455678888050i33i206279278&mode=ECB&keylen=128&key=1234567890123456&iv=1234567890123456&bpkcs=pkcs7padding&session=FH4xlZr0LlqsJVtwfbVw&aes=ac518f9f8429369bf129da6d6633cbb2&encoding=hex&type=0

参考工程:https://github.com/zhenghaishu/AES128-for-iOS



http://pan.baidu.com/s/1jHmo9Pc


2017-02-16 11:36:27 L_weiguo 阅读数 851

1.使用

 NSString *originalStr=@"AES";  
  
    //加密  
    NSString *encryStr = [AES128Util AES128Encrypt:originalStr key:AES_KEY];  
    //解密  
    NSString *decryStr = [AES128Util AES128Decrypt:encryStr key:AES_KEY];  
      
    NSLog(@"\n加密前:%@\n加密后:%@ \n解密后:%@",originalStr,encryStr,decryStr);

2.具体实现类  .h文件

#import <Foundation/Foundation.h>  
  
@interface AES128Util : NSObject  
  
+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key;  
  
+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key;  
  
@end  

.m 文件

#import "AES128Util.h"  
#import <CommonCrypto/CommonCryptor.h>  
#import "GTMBase64.h"  
  
@implementation AES128Util  
  
+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key  
{  
    char keyPtr[kCCKeySizeAES128+1];  
    memset(keyPtr, 0, sizeof(keyPtr));  
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
      
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];  
    NSUInteger dataLength = [data length];  
      
    size_t bufferSize = dataLength + kCCBlockSizeAES128;  
    voidvoid *buffer = malloc(bufferSize);  
    size_t numBytesEncrypted = 0;  
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,  
                                          kCCAlgorithmAES128,  
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,  
                                          keyPtr,  
                                          kCCBlockSizeAES128,  
                                          NULL,  
                                          [data bytes],  
                                          dataLength,  
                                          buffer,  
                                          bufferSize,  
                                          &numBytesEncrypted);  
    if (cryptStatus == kCCSuccess) {  
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];  
        //return [GTMBase64 stringByEncodingData:resultData];  
        return [self hexStringFromData:resultData];  
  
    }  
    free(buffer);  
    return nil;  
}  
  
  
+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key  
{  
    char keyPtr[kCCKeySizeAES128 + 1];  
    memset(keyPtr, 0, sizeof(keyPtr));  
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
      
    //NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];  
      
    NSData *data=[self dataForHexString:encryptText];  
      
    NSUInteger dataLength = [data length];  
    size_t bufferSize = dataLength + kCCBlockSizeAES128;  
    voidvoid *buffer = malloc(bufferSize);  
      
    size_t numBytesCrypted = 0;  
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,  
                                          kCCAlgorithmAES128,  
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,  
                                          keyPtr,  
                                          kCCBlockSizeAES128,  
                                          NULL,  
                                          [data bytes],  
                                          dataLength,  
                                          buffer,  
                                          bufferSize,  
                                          &numBytesCrypted);  
    if (cryptStatus == kCCSuccess) {  
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];  
        return [[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] autorelease];  
    }  
    free(buffer);  
    return nil;  
}  
  
// 普通字符串转换为十六进  
+ (NSString *)hexStringFromData:(NSData *)data {  
    Byte *bytes = (Byte *)[data bytes];  
    // 下面是Byte 转换为16进制。  
    NSString *hexStr = @"";  
    for(int i=0; i<[data length]; i++) {  
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i] & 0xff]; //16进制数  
        newHexStr = [newHexStr uppercaseString];  
          
        if([newHexStr length] == 1) {  
            newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];  
        }  
          
        hexStr = [hexStr stringByAppendingString:newHexStr];  
          
    }  
    return hexStr;  
}  
  
//参考:http://blog.csdn.net/linux_zkf/article/details/17124577  
//十六进制转Data  
+ (NSData*)dataForHexString:(NSString*)hexString  
{  
    if (hexString == nil) {  
          
        return nil;  
    }  
      
    const char* ch = [[hexString lowercaseString] cStringUsingEncoding:NSUTF8StringEncoding];  
    NSMutableData* data = [NSMutableData data];  
    while (*ch) {  
        if (*ch == ' ') {  
            continue;  
        }  
        char byte = 0;  
        if ('0' <= *ch && *ch <= '9') {  
              
            byte = *ch - '0';  
        }else if ('a' <= *ch && *ch <= 'f') {  
              
            byte = *ch - 'a' + 10;  
        }else if ('A' <= *ch && *ch <= 'F') {  
              
            byte = *ch - 'A' + 10;  
              
        }  
          
        ch++;  
          
        byte = byte << 4;  
          
        if (*ch) {  
              
            if ('0' <= *ch && *ch <= '9') {  
                  
                byte += *ch - '0';  
                  
            } else if ('a' <= *ch && *ch <= 'f') {  
                  
                byte += *ch - 'a' + 10;  
                  
            }else if('A' <= *ch && *ch <= 'F'){  
                  
                byte += *ch - 'A' + 10;  
                  
            }  
              
            ch++;  
              
        }  
          
        [data appendBytes:&byte length:1];  
          
    }  
      
    return data;  
}  


没有更多推荐了,返回首页