CommonCrypto 为苹果提供的系统加密接口,支持iOS 和 mac 开发;

不仅限于AES加密,提供的接口还支持其他DES,3DES,RC4,BLOWFISH等算法,

本文章主要讨论AES在iOS的处理,从接口资料描述和测试来看CommonCrypto 与AES相关的一些小结,

  • 支持的AES key size 有 128位,192位,256位
  • 目前仅支持 AES 128位 blocks 分组
  • 数据填充方式:Nopadding,PKCS7 两种
  • 分组模式:cbc,ecb 两种默认为 cbc

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #e44448 }
span.s1 { color: #d28f5a }
span.s2 { }

#import <CommonCrypto/CommonCryptor.h>

1. 主要接口CCCrypt

/*!
    @function   CCCrypt
    @abstract   一个接口来处理加密解密方式.
                还可以使用方式二:下面会有示例说明 ,调用流程分几步 ,CCCrytorCreate(),
                CCCryptorUpdate(), CCCryptorFinal(), and CCCryptorRelease().

    @param      alg             加解密使用的算法.

    @param      op              操作类型解密或解密: kCCEncrypt or
                    kCCDecrypt.

    @param      options         填充方式式通常是kCCOptionPKCS7Padding,默认分组模式cbc,.

    @param      key             密钥. 

    @param      keyLength       密钥长度.

    @param      iv              加密使用的向量参数,cbc模式需要,16个字节,ecb模式不需要,. 

    @param      dataIn          输入的数据. 

    @param      dataInLength    输入的数据长度.

    @param      dataOut         输出的数据. 

    @param      dataOutAvailable 输出数据时需要的可用空间大小.  

    @param      dataOutMoved    成功之后实际占用的空间大小. 

    @result     结果在为CCCryptorStatus 枚举
 */

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, 等. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, 等. */
    CCOptions options,      /* kCCOptionPKCS7Padding, 等. */
    const void *key,
    size_t keyLength,
    const void *iv,         /* 可选的向量 */
    const void *dataIn,     /*输入*/
    size_t dataInLength,
    void *dataOut,          /* 输出 */
    size_t dataOutAvailable,
    size_t *dataOutMoved)

如下的封装调用方式,可以根据需要修改

AES_256_cbc 加密或解密

NSData *aes_cbc_256(NSData *inData,NSData *key,CCOperation coType)
{
    NSData *retData = nil;
    if (!inData || !key) {
        return nil;
    }

    ) {
        return nil;
    }

    NSUInteger dataLength = [inData length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = ;
    CCCryptorStatus cryptStatus;
    
  //ecb 模式不需要使用 iv,cbc模式需要,当cbc模式时,如果不传iv,则默任全0 Byte iv[] = {}; ; i < ; i++) { iv[i] = ; } //加密 if (coType==kCCEncrypt) { cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,//使用AES算法 kCCOptionPKCS7Padding, key.bytes, kCCKeySizeAES256, iv, [inData bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); } //解密 else if(coType ==kCCDecrypt) { cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key.bytes, kCCKeySizeAES256, iv, [inData bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); } if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); return retData; }

测试:

        Byte bkey[] = {};
        ; i < ; i++) {
            bkey[i] = ;
        }
        NSData *dkey = [NSData dataWithBytes:bkey length:];
        NSLog(@"key:%@",dkey);

        NSString *srcStr = @"this is test hello string";
        NSData *srcData = [srcStr dataUsingEncoding:NSASCIIStringEncoding];
        NSLog(@"src:%@",srcData);
        NSData *encData = aes_cbc_256(srcData, dkey, kCCEncrypt);
        NSLog(@"enc:%@",encData);

        NSData *decData = aes_cbc_256(encData, dkey, kCCDecrypt);
        NSLog(@"dec:%@",decData);

        ) {
            NSLog(@"test PASS");
        }
        else
        {
            NSLog(@"NO PASS");
        }

输出日志

-- :::] key:<       >
-- :::] src:<   2068656c 6c6f2073 7472696e >
-- :::] enc:< f51ac83c bd687f22 d9591dfe e413a769 89b07c41 b047d061 8e0a590c>
-- :::] dec:<   2068656c 6c6f2073 7472696e >
-- :::] test PASS

2. 另外 为了测试,在mac下安装了openssl 1.1.0c的库

在终端下使用 openssl 命令来配合测试,

在终端下openssl 命令加密数据,在ios上解密

在ios上加密数据,在mac终端下使用openssl 命令解密

配合测试的流程如上,我已在本机测试,不在这里贴示例了,说下openssl的命令吧

主要使用openssl enc 命令,如下命令的帮助,其中部分用中文备注了

Valid options are:
 -help          查看帮助-ciphers       查看算法列表
 -in infile     输入文件
 -out outfile   输出结果文件
 -pass val      密钥的密码
 -e             加密
 -d             解密
 -p             打印key和iv-P             打印key和iv并退出,这个是大写,实测不会生成out,用上面的小写-v             Verbose output
 -nopad         Disable standard block padding
 -salt          Use salt in the KDF (default)
 -nosalt        Do not use salt in the KDF
 -debug         Print debug info
 -a             Base64 encode/decode, depending on encryption flag
 -base64        Same as option -a
 -A             Used with -[base64|a] to specify base64 buffer as a single line
 -bufsize val   Buffer size
 -k val         Passphrase
 -kfile infile  Read passphrase from file
 -K val         密钥key,16进制-S val         Salt, in hex
 -iv val        向量iv,16进制-md val        Use specified digest to create a key from the passphrase
 -none          Don't encrypt
 -*             Any supported cipher
 -engine val    Use engine, possibly a hardware device

如配合上面测试的 aes_256_cbc 方式,使用上面的密钥和key

加密:

openssl enc -aes--cbc -e -K  -iv  -in srcTest.txt -out enc.txt -p

解密:

openssl enc -aes--cbc -d -K  -iv  -in enc.txt -out dec.txt -p

3. 对称加密分步方式二

主要接口

//创建加密器CCCryptorRef
CCCryptorStatus CCCryptorCreate( CCOperation op, /* kCCEncrypt, etc. */ CCAlgorithm alg, /* kCCAlgorithmDES, etc. */ CCOptions options, /* kCCOptionPKCS7Padding, etc. */ const void *key, /* raw key material */ size_t keyLength, const void *iv, /* optional initialization vector */ CCCryptorRef *cryptorRef) /* RETURNED */
//获取输出数据的最大长度 size_t CCCryptorGetOutputLength( CCCryptorRef cryptorRef, size_t inputLength, bool final)
//加密处理 CCCryptorStatus CCCryptorUpdate( CCCryptorRef cryptorRef, const void *dataIn, size_t dataInLength, void *dataOut, /* data RETURNED here */ size_t dataOutAvailable, size_t *dataOutMoved) /* number of bytes written */ //处理最后的数据块 CCCryptorStatus CCCryptorFinal( CCCryptorRef cryptorRef, void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved) /* number of bytes written */
//释放 CCCryptorStatus CCCryptorRelease( CCCryptorRef cryptorRef)

如下封装示例调用

aes_256_cbc 加密或解密

NSData *TEST_AES(NSData *indata,CCOperation otype)
{
    NSData *retData = nil;
//测试的密钥或向量 Byte tkey[] = {}; ; i < ; i++) { tkey[i] = ; } Byte iv[] = {}; ; i < ; i++) { iv[i] = ; } CCCryptorRef cryptor = NULL; CCCryptorStatus ccret;
  //创建加密解密器 if (otype==kCCEncrypt) { ccret = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor); } else if (otype == kCCDecrypt) { ccret = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor); } if (ccret!=kCCSuccess) { return nil; } size_t bufsize = ; size_t moved = ; size_t total = ;
  //获取最大长度 bufsize = CCCryptorGetOutputLength(cryptor, indata.length, true); char * buf = (char*)malloc(bufsize); bzero(buf, bufsize);
  //加解密 ccret = CCCryptorUpdate(cryptor, indata.bytes,indata.length, buf, bufsize, &moved); total += moved; if (ccret!=kCCSuccess) { return nil; }
  //处理最后的数据块 ccret = CCCryptorFinal(cryptor, buf+total, bufsize-total, &moved); if (ccret!=kCCSuccess) { return nil; } total +=moved; CCCryptorRelease(cryptor);
   retData = [NSData dataWithBytes:buf length:total]; free(buf); return retData; }

测试使用

        NSString *srcStr = @"this is test hello string";
        NSData *srcData = [srcStr dataUsingEncoding:NSASCIIStringEncoding];

        NSData *encData = TEST_AES(srcData, kCCEncrypt);
        NSData *decData = TEST_AES(encData, kCCDecrypt);

        NSLog(@"src:%@",srcData);
        NSLog(@"enc:%@",encData);
        NSLog(@"dec:%@",decData);

        ) {
            NSLog(@"PASS");
        }
        else
        {
            NSLog(@"NP_PASS");
        }

输出日志

-- :::] src:<   2068656c 6c6f2073 7472696e >
-- :::] enc:< f51ac83c bd687f22 d9591dfe e413a769 89b07c41 b047d061 8e0a590c>
-- :::] dec:<   2068656c 6c6f2073 7472696e >
-- :::] PASS

两种方式测试的结果一致;

可见第一种方式其实是苹果内部对第二种方式进一步的封装处理。

4. 总结:

关于在iOS上的对称加密方式;

  • 使用本文苹果API,本文:http://www.cnblogs.com/cocoajin/p/6150203.html
  • 使用openssl ,见文章:http://www.cnblogs.com/cocoajin/p/6121706.html
  • 使用 Cryptopp,见文章:http://www.cnblogs.com/cocoajin/p/6112562.html

封装工具:https://github.com/cocoajin/Security-iOS

iOS CommonCrypto 对称加密 AES ecb,cbc的更多相关文章

  1. 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

    一. AES对称加密: AES加密 分组 二. 分组密码的填充 分组密码的填充 e.g.: PKCS#5填充方式 三. 流密码:   四. 分组密码加密中的四种模式: 3.1 ECB模式 优点: 1. ...

  2. [Node.js] 对称加密、公钥加密和RSA

    原文地址:http://www.moye.me/2015/06/14/cryptography_rsa/ 引子 对于加解密,我一直处于一种知其然不知其所以然的状态,项目核心部分并不倚重加解密算法时,可 ...

  3. JDK自带方法实现AES对称加密

    请看代码. 1 package jdbc.pro.lin; 2 3 import java.security.InvalidAlgorithmParameterException; 4 import ...

  4. java对称加密(AES)

    java对称加密(AES) 博客分类: Java javaAES对称加密  /** * AESHelper.java * cn.com.songjy.test * * Function: TODO * ...

  5. AES对称加密

    import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.Secre ...

  6. 使用Aes对称加密解密Web.Config数据库连接串

    现在很多公司开始为了保证数据库的安全性,通常会对Web.Config的数据库连接字符串进行加密.本文将介绍学习使用Aes加密解密数据库连接字符串.本文采用MySql数据库. AES概念简述 AES 是 ...

  7. AES —— JAVA中对称加密和解密

    package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingException; impo ...

  8. AES,RSA对称加密和非对称加密

    1.关于RSA加密机制:是非对称加密方式,两个钥,公钥和私钥,公钥用于加密数据,可以分享给其他用户,私钥可以用于解密用公钥加密的数据,关于安全问题是公钥泄露不会影响安全问题,公钥与私钥是一一对应的关系 ...

  9. 对称加密之AES、压缩解压以及压缩加密解密解压综合实战

    AES 压缩解压 压缩加密解密解压 对称加密: 就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密.密钥是控制加密及解密过程的指令.算法是一组规则,规定如何进行加密和解密.   因此加密的安 ...

随机推荐

  1. python 小功能

    目录 1.上传文件 2.验证码 一.上传文件 首先了解一下 request.FILES : 字典 request.FILES 中的每一个条目都是一个UploadFile对象.UploadFile对象有 ...

  2. WCF局域网内使用代理无法访问解决方法

    问题描述 在大部分事业单位上网都是需要使用代理的,前几天带着一个同事写的程序过来部署,部署以后各个客户端通过WCF相互通讯,那么其中一个地方在本地局域网测试是没有问题的. 后发现一部分是原因是由于代理 ...

  3. django复习笔记3:实战

    1.初始化 2.配置后台,增加测试数据 3.测试urls/views/templates 4.增加静态资源 5.修改样式 6.模版继承 7.增加博文主页 8.增加表单 9.完善新增页面和编辑页面的表单 ...

  4. “mybatis 中使用foreach 传

    为了帮助网友解决“mybatis 中使用foreach 传”相关的问题,中国学网通过互联网对“mybatis 中使用foreach 传”相关的解决方案进行了整理,用户详细问题包括:mybatismap ...

  5. [c#]params可变参数

    摘要 在项目中多多少少会用到params这个关键字,来修饰参数,它的作用,让该参数的个数是可变的,并且可变参数必须是方法的最后一个参数.但如何判断到底有没有为该参数传递值,怎么判断? 一个例子 sta ...

  6. document.createElement

    document.createElement()的用法 document.createElement()是在对象中创建一个对象,要与appendChild() 或 insertBefore()方法联合 ...

  7. linux面试题及答案

    http://www.cnblogs.com/itech/archive/2011/02/12/1952857.html 一.填空题:1. 在Linux系统中,以 文件 方式访问设备 .2. Linu ...

  8. C语言初学者代码中的常见错误与瑕疵(13)

    https://www.cpfn.org/bbs/viewtopic.php?f=85&t=5940&sid=ccbcf716d21191452e7c08a97b502337& ...

  9. node.js关于传送数据的二三事

    配置好node环境后 书写代码 目录结构: . 代码: <!DOCTYPE html> <html lang="en"> <head> < ...

  10. rac 11g_生产库日志组损坏处理

    原创作品,出自 "深蓝的blog" 博客,转载时请务必注明出处,否则有权追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/ar ...