iOS加解密最重要的干货:CCCrypt

需要引入框架#import <CommonCrypto/CommonCryptor.h>
函数定义:

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, etc. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, etc. */ CCOptions options, /* kCCOptionPKCS7Padding, etc. */ const void *key, size_t keyLength, const void *iv, /* optional initialization vector */ const void *dataIn, /* optional per op and alg */ size_t dataInLength, void *dataOut, /* data RETURNED here */ size_t dataOutAvailable, size_t *dataOutMoved) 

下面就跟我一起探秘CCCrypt吧

函数介绍
    @function   CCCrypt
    @abstract   Stateless, one-shot encrypt or decrypt operation. This basically performs a sequence of CCCrytorCreate(), CCCryptorUpdate(), CCCryptorFinal(), and CCCryptorRelease(). 

无状态的一次加密解密方法,是CCCrytor系列函数基本实现,翻译不准确,随便凑合看吧。

参数说明
  1. CCOperation op:Defines the basic operation: kCCEncrypt or kCCDecrypt.
    很简单,加密kCCEncrypt,解密kCCDecrypt
  2. CCAlgorithm alg:Defines the encryption algorithm.
    加密算法,枚举如下:
enum {
    kCCAlgorithmAES128 = 0,
    kCCAlgorithmAES = 0,
    kCCAlgorithmDES,
    kCCAlgorithm3DES,       
    kCCAlgorithmCAST,       
    kCCAlgorithmRC4,
    kCCAlgorithmRC2,   
    kCCAlgorithmBlowfish    
};
typedef uint32_t CCAlgorithm; 

主要看一下AES和DES

  • kCCAlgorithmAES128 & kCCAlgorithmAES
    kCCAlgorithmAES128kCCAlgorithmAES是一样的,AES分组加密,固定的加密块是128位,即16个字节,跟密钥长度无关,咱们常说的128、192、256主要指的就是密钥长度(当然还有加密轮数也不一样),加密运算操作相同,所以这两个是一样的
  • kCCAlgorithmDES:
    DES明文按照 64 位进行分组,分组后的明文与密钥按位替代或交换的方法形成密文组。 密钥的长度是 64 位即8个字节(其实是56位,其中有8位是奇偶校验位)
  • kCCAlgorithm3DES
    3DES是针对DES算法密钥过短、存在安全性的问题而改进的一个措施,被称为“3DES”。其实只是通过简单的执行3次DES来达到增加密钥长度和安全而已,3DES算法在对明文M进行加密时,采用了三次加密过程,其中第一次和第三次是采用DES的加密算法,第二次采用的则是解密算法,从而得到最终的密文C。这种加密过程为“加密-解密-加密”,所以又称为EDE(Encrypt-Decrypt-Encrypt)方案
  1. CCOptions options
    选择的补码方式,以及是否选择ECB模式,默认是CBC模式
enum {
    /* options for block ciphers */
    kCCOptionPKCS7Padding   = 0x0001,
    kCCOptionECBMode        = 0x0002
    /* stream ciphers currently have no options */ }; typedef uint32_t CCOptions; 
  1. const void *key
    传入的密钥,经过从cstring utf8转成字节类型
char keyPtr[kCCKeySizeAES256 + 1];//选择aes256加密,所以key长度应该是kCCKeySizeAES256,32位
bzero(keyPtr, sizeof(keyPtr));//清零 [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];//秘钥key转成cString 

需要注意的是如果这里申请的空间不够,加解密会出现问题的,传入的密钥过长,会自动截取,密钥长度不够,自动补全

  1. size_t keyLength:这里是真正决定密钥长度的地方,可选列表是下面这些
enum {
    kCCKeySizeAES128          = 16,
    kCCKeySizeAES192          = 24,
    kCCKeySizeAES256          = 32,
    kCCKeySizeDES             = 8, kCCKeySize3DES = 24, kCCKeySizeMinCAST = 5, kCCKeySizeMaxCAST = 16, kCCKeySizeMinRC4 = 1, kCCKeySizeMaxRC4 = 512, kCCKeySizeMinRC2 = 1, kCCKeySizeMaxRC2 = 128, kCCKeySizeMinBlowfish = 8, kCCKeySizeMaxBlowfish = 56, }; 
关于CCCrypt中的key和keyLength

AES数据块长度为128位,所以IV长度需要为16个字符(ECB模式不用IV),密钥根据指定密钥位数分别为16、24、32个字符,IV与密钥超过长度则截取,不足则在末尾填充'\0'补足

  1. iv:偏移向量,CBC模式下需要,不传默认16位0,ECB不需要
  2. const void *dataIn
    要加解密的数据data.bytes
  3. size_t dataInLength
NSUInteger dataLength = data.length;
  1. void *dataOut :Result is written here
  2. size_t dataOutAvailable:The size of the dataOut buffer
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);

以AES加密为例解释一下,128、192、256这里都是一样的,AES固定加密块为128位(16个字节),分组之后如果加密块16字节,自动补全,如果加密data.length正好是16的倍数,则需要在后面再补全一个加密块的长度,所以这里申请的空间需要比被操作的数据长度多一个密码块的长度

  1. size_t dataOutMoved:操作成功之后,被写入dataout的字节长度
    所以最后我们根据
    dataOutMoved从dataout截取我们最后获得的数据
if (cryptStatus == kCCSuccess) {
        NSData * result = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        return result;
    }

That's all !!!

猜你喜欢

转载自www.cnblogs.com/Free-Thinker/p/11425724.html