zoukankan      html  css  js  c++  java
  • 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与密钥超过长度则截取,不足则在末尾填充''补足

    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 !!!

  • 相关阅读:
    leetcode 890. 查找和替换模式 Python
    TensorFlow-GPU+cuda8+cudnn6+anaconda安装遇到的版本错误
    leetcode 921. 使括号有效的最少添加(Python)
    BFC概念详解及应用
    做一个网页阅读百分比指示器
    margin-bottom和vertical-align的区别
    MD5算法
    Array.prototype.slice.call()方法详解
    String stringbuffer StringBuilder
    价值观
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/11425724.html
Copyright © 2011-2022 走看看