• 先了解下 DES ECB模式 ECB模式: 优点: 1. 简单; 2. 有利于并行计算; 3. 误差不会被传递; 缺点: 1. 不能隐藏明文的模式; 2. 可能对明文进行主动攻击; DES ECB(电子密本方式)其实非常简单,就是将数据按照8...

    先了解下 DES ECB模式

    ECB模式:
    优点:
    1. 简单;
    2. 有利于并行计算;
    3. 误差不会被传递;
    缺点:
    1. 不能隐藏明文的模式;
    2. 可能对明文进行主动攻击;

    DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

    CBC模式:
    优点:
    1. 不容易主动攻击,安全性好于ECB,是SSL、IPSec的标准;
    缺点:
    1. 不利于并行计算;
    2. 误差传递;
    3. 需要初始化向量IV;

    DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
    加密步骤如下:
    1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
    2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
    3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
    4. 之后的数据以此类推,得到Cn
    5. 按顺序连为C1C2C3......Cn即为加密结果。

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

    #import <Foundation/Foundation.h>
    #import <CommonCrypto/CommonCryptor.h>
    #import "ConverUtil.h"
    #import "Constants.h"
    
    @interface DES : NSObject
    //加密
    - (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key;
    //解密
    -(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key;
    
    @end

    加密类的实现类:

    #import "DES.h"
    
    @implementation DES
    //DES_IV 自己定义的一个字符串 八个字节 一定要是八个字节
    -(Byte *) getIv{
        
        NSString *testString = DES_IV;
        NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
        //    for(int i=0;i<[testData length];i++)
        //        printf("testByte = %d\n",testByte[i]);
        return (Byte *)[testData bytes];
    }
    //plainText需加密 字符串 key 定义好的 加密 解密 钥匙
    - (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key{
        
        Byte *iv=[self getIv];
        
    //    NSString *escape=[plainText stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
    //    return escape;
        
        NSData* data=[plainText dataUsingEncoding: NSUTF8StringEncoding];
        
        NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
        
        char buffer[bufferSize];
        
        memset(buffer, 0,sizeof(buffer));
        
        size_t bufferNumBytes;
        
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                              
                                              kCCAlgorithmDES,
                                              
                                              kCCOptionPKCS7Padding,
                                              
                                              [key UTF8String],
                                              
                                              kCCKeySizeDES,
                                              
                                              iv   ,
                                              
                                              [data bytes],
                                              
                                              [data length],
                                              
                                              buffer,
                                              
                                              bufferSize,
                                              
                                              &bufferNumBytes);
        
        if (cryptStatus ==kCCSuccess) {
            
            NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
            
            return [ConverUtil parseByteArray2HexString:[data bytes] count:bufferNumBytes] ;
            //        NSLog(@"objccipherTextBytes:%@",[XYDES dataToHex:data]);
            //        ciphertext = [GTMBase64 stringByEncodingData:data];
            //        NSLog(@"objccipherTextBase64:%@",ciphertext);
        }
        
        return nil;
    }
    
    -(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key{
        
        Byte *iv=[self getIv];
        
        NSData* data = [ConverUtil parseHexToByteArray:cipherText];
        
        NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
        
        char buffer[bufferSize];
        
        memset(buffer, 0,sizeof(buffer));
        
        size_t bufferNumBytes;
        
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              
                                              kCCAlgorithmDES,
                                              
                                              kCCOptionPKCS7Padding,
                                              
                                              [key UTF8String],
                                              
                                              kCCKeySizeDES,
                                              
                                              iv,
                                              
                                              [data bytes],
                                              
                                              [data length],
                                              
                                              buffer,
                                              
                                              bufferSize,
                                              
                                              &bufferNumBytes);
        
        NSString* plainText = nil;
        
        if (cryptStatus ==kCCSuccess) {
            
            NSData *plainData =[NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
            
            plainText = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
        }
        
        return plainText;
    }
    
    @end

    下面是转码类,主要是16进制和字节的转化 
    头文件:
    #import <Foundation/Foundation.h>
    
    @interface ConverUtil : NSObject
    
    /**
     64编码
     */
    +(NSString *)base64Encoding:(NSData*) text;
    
    /**
     字节转化为16进制数
     */
    +(NSString *) parseByte2HexString:(Byte *) bytes;
    
    /**
     字节数组转化16进制数
     */
    +(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count;
    
    /*
     将16进制数据转化成NSData 数组
     */
    +(NSData*) parseHexToByteArray:(NSString*) hexString;
    
    @end

    实现类:

    #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++;
            }
        }
        
        return hexStr;
    }
    
    
    /**
     字节数组转化16进制数
     */
    +(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count
    {
        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++;
            //        }
            for (int i=0;i< count;i++)
            {
                NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
                
                if([hexByte length]==1)
                    [hexStr appendFormat:@"0%@", hexByte];
                else
                    [hexStr appendFormat:@"%@", hexByte];
                
                //            i++;
            }
        }
        
        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];
        
        return newData;
    }
    
    @end



    展开全文
  • IOS 使用AES/ECB/PKCS7Padding 加密、解密数据 AES/ECB/PKCS7Padding + UTF-8、UTF-16、ASCII、Base64、十六进制
    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框架的问题吧,暂不深究。




    展开全文
  • // AES加密之ECB128模式 Padding - (NSString *)cs_aes128EncryptECBModeWithkey:(NSString *)key { if (key.length == 0) { key = @"AES128Key"; } char keyPtr[kCCKeySizeAES128+1]; memset...
    #import <CommonCrypto/CommonCryptor.h>
    
    
    
    // AES加密之ECB128模式 Padding
    
    - (NSString *)cs_aes128EncryptECBModeWithkey:(NSString *)key {
    
            if (key.length == 0) {
    
            key = @"AES128Key";
    
        }
    
        char keyPtr[kCCKeySizeAES128+1];
    
        memset(keyPtr, 0, sizeof(keyPtr));
    
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
        NSData* data = [self 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];
    
            NSString *base64String = [resultData base64EncodedStringWithOptions:0];
    
            return base64String;
    
        }
    
        free(buffer);
    
        return nil;
    
    }

     

    展开全文
  • AES-128 ECB 加密有感

    2014-02-14 16:55:16
    最近要搞一个加密。很是蛋疼。 原本单片机和上位机发送数据就是非常简单的。 这个项目相当复杂。每次数据命令都差不多1K,一次数据都要1K以上。是通过GPRS发送的。...这些难缠的问题再前一阶段已经解决了。...

    最近要搞一个加密。很是蛋疼。

    原本单片机和上位机发送数据就是非常简单的。

    这个项目相当复杂。每次数据命令都差不多1K,一次数据都要1K以上。是通过GPRS发送的。

    这些难缠的问题再前一阶段已经解决了。

    现在老师,还让我们做AES加密。是对我们做控制的人来说还确实有点难度啊 。

    在网上找了一大堆资料,总有把AES加密有点弄懂了。这里推荐一个人写的博客。再次非常感谢这位大侠。http://hi.baidu.com/mallor/item/89dad214d1f1fe0dd1d66d33

    写的详单详细。

    我再啰嗦一下,我对AES的心得。

    其实AES就是对16byte(128bit)数据进行加密的过程。说白了就是把128位通过一系列的变化变成另一个128数据。

    这里主要用到2个关键的东西。密钥(key)这个是绝对不能省的。key要先扩张,然后进行10次的行列变化,与数据进行抑或操作。最终才能得到加密后的数据。

    此位还有一个东西是非常让我困惑的,就是初始向量(IV)。这个地方自己当时也纳闷了很久,不知道怎么样。其实说真的,还真可以不用他。用她只是可以把加密变得更难破解。

    那我就来具体说一下怎么用。

    呵呵 废话有点多了。

    u8 data[16]={ 0x00,0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,0x0c, 0x0d, 0x0e, 0x0f};

    u8IV[16]={ 0x30, 0x31, 0x32, 0x33,
      0x34, 0x35, 0x36, 0x37,
      0x38, 0x39, 0x61, 0x62,
      0xd63, 0x64, 0x65,0x66};

    其实只要把

     for(i=0;i<16;i++)
     {
      data[i]=data[i]^IV[i];
     }

    然后再把data作为新的数据加密就OK了。

    当然你也可以不用他。

    那么如果数据不是16的倍数改怎么办呢。这里我们就用到的数据扩张

    AES支持支持几种填充:NoPadding,PKCS5Padding,ISO10126Padding,PaddingMode.Zeros;PaddingMode.PKCS7;

    这里要说明一下PKCS5Padding和PKCS7Padding是一样的。

    详细大家可以参考http://www.cnblogs.com/midea0978/articles/1437257.html

    我也再说一下PKCS7 就是数据少几个就填充几个。

    比如数据{1,2,3,4,5,6,7,8,9,10}

    少了6个

    那么就填充6个6(注意是0x06,而不是字符6,字符6实际上是0x36)

    {1,2,3,4,5,6,7,8,9,10,6,6,6,6,6,6}

    注意一定要是16个数据(1个数据是8位,这样就是128位)这样才能进行AES加密。

    切记。

    PaddingMode.Zeros

    这个填充方式,个人比较喜欢。就是在后面补充0.

    无论缺多少就补多少个0。

    再提醒一下就是如果刚满16个,那就要在补充称16个字节。一定要比原先的多。(每种补充都要满足这样。这里非常容易被忽略).

    也就是说如果{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}

    PaddingMode.Zeros模式

    就要补充称{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}

    PKCS7Padding模式就要{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}.这样再代入加密算法才是最正直的AES。

    祝大家好运

    http://www.oschina.net/code/snippet_242957_9931

    这是C#写的。大家可以参考下。

    C++的程序 http://hi.baidu.com/mallor/item/89dad214d1f1fe0dd1d66d33

    这2个地方都非常好。

    总之遇到困难,觉得不能退缩。要一步一步往前走,相信前途一定会是光明的。

    我就是这样从一点也不知道然后在把C,和C#的加密解密方法给统一对应起来。C#都是集成的,引用非常简单。C里面就必须彻底搞清楚,才能用C加密的东西在C#下可以正常解密!!!

    展开全文
  • IOS AES加密之ECB128模式

    2019-07-07 15:35:26
    1、AES加密模式有好几种,网上大多是CBC、256模式,找了好久才找到解决ECB128模式加密。 AES需要导入头文件 #import <CommonCrypto/CommonCryptor.h> #import "GTMBase64.h" //加密后的数据在Base64转字符...

     

    1、AES加密模式有好几种,网上大多是CBC、256模式,找了好久才找到解决ECB128模式加密。

    AES需要导入头文件

    #import <CommonCrypto/CommonCryptor.h>

    #import "GTMBase64.h" //加密后的数据在Base64转字符串类型

    +(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];
        }
        free(buffer);
        return nil;
    }

     

    直接放 Demo: AES/ECB模式128Demo下载 密码:qj57

     

    转载于:https://www.cnblogs.com/qq95230/p/5908175.html

    展开全文
  • AES加密的过程: ...ECB模式: 分组加密,分组解密。 ISO10126: 这是填充方式的一种,旨将原文的长度边长组的大小的整数倍。 最后一个填充是填充的字节数,其它位随机数。代码如下:
  • 前言 谈谈AES加密,网上有很多的版本,当我没有真正在加密安全问题前,总以为百度出来某个AES加密算法就可以直接使用,实际上当我真正要做加密时,遇到了很多的坑,原来不是拿过来就能用的。...
  • PHP代码 和 iOS 代码 摘自 http://blog.toright.com/posts/2657/ios-objective-c-與-php-des-加解密演算法實作.html 三个平台共用 一个密匙,尽量为8的倍数 1.php代码 /** * PHP DES 加密程式 * * @param $key ...
  • ios开发 AES-128-ECB加密

    2020-06-03 23:32:15
    之前遇到的需求,ios上没有类似的实现。搞了好久在网上搜了很多资料都不能解决最后找到了一个c/c++的底层源码,才实现了最后整理了下上传了。是个ios的demo很详细你定能看懂的。运行在xcode环境下,关键算法的文件是...
  • 最近忙于android和iOS的项目,写完了android的DES 的ECB模式加密解密(相关连接:http://blog.csdn.net/vipa1888/article/details/8086037),又 回到了Ios上面,因为本人也是最近今年开始研究ios的,所以Ios上面...
  • [objc] view ...//////////////AES加密方式: AES 128 ECB PKCS7Padding 16进制加密解密 //////////////   NSString *originalStr=@"AES";     //加密   NSString *encryStr = [AES128U
  • iOS DES ECB 模式加密

    2019-01-02 05:26:13
    //iOS DES ECB 模式加密 #import &lt;CommonCrypto/CommonCryptor.h&gt; static Byte iv[] = {1,2,3,4,5,6,7,8}; +(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key { ...
  • AES加密默认为CBC模式,添加一个标识即可变为ECB模式。 ECB模式不需要偏移量。 字符串处理一般为base64编码,字符集为UTF-8。 代码示例如下: // // AESTool.h // // Created by 王盛魁 on 2020/4/3. // Copyright ...
  • 项目开发过程中,经常会使用各种加密手段来保证数据的安全性,常见的有MD5,DES,AES等等。摘取百度百科AES词条的简介:AES即高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称...
  • iOS AES-128-ECB 加密

    2019-10-13 20:38:50
    最近在做PHP和iOS项目,iOS这边的aes加密PHP解密不了,然后去站长工具解密iOS加密的密文才知道是iOS加密和解密出了问题 这篇博文很好解决了这个问题https://www.jianshu.com/p/c05d6fc8ccc2 ...
  • 有谁做过易宝IOS充值接口?现在我出现的问题是加密了,易宝那边解析不了,有人能帮我解决下么? 高分补偿!! 补充一下是128位的不是256的加密
  • AES/ECB/PKCS5PADDING

    2020-06-13 23:30:26
    最近需要和银行pos做数据通讯,银行端算法为java实现的 AES/ECB/PKCS5PADDING我也改不了, c/c++这边实现ECB算法本来就少,PKCS5PADDING的更是没有,索性自己动手。工作原因c和java都得熟悉,因此把java端和c/c++...
1 2 3 4 5 ... 20
收藏数 1,210
精华内容 484