常用加密算法:
DES:Data Encryption Standard, 即数据加密算法, 它是 IBM 公司于 1975 年研究成功并公开发表的
DES(数据加密标准)原理:
DES 是一个分组加密算法, 它以 64 位为分组对数据加密 64 位一组的明文从算法的一端输入, 64 位的密文从另一段输出它是一个对称算法: 加密和解密用的是同一个算法
密钥通常表示为 64 位的数, 但每个第 8 位都用作奇偶校验, 可以忽略, 所以密钥长度为 56 位密钥可以是任意的 56 位的数, 且可在任意的时候改变
DES 算法只不过是加密的两个基本技术混乱和扩散的组合, 即先代替后置换, 它基于密钥作用于明文, 这是一轮(round),DES 在明文分组上实施 16 轮相同的组合技术
DES 现在用的比较少, 因为它的加密强度不够, 能够暴力破解!! 还有一个 3DES, 原理和 DES 几乎是一样的, 只是使用 3 个密钥, 对相同的数据执行三次加密, 增强加密强度, 但是要维护 3 个密钥, 大大增加了维护成本!
AES: 高级加密标准, 这个标准用来替代原先的 DES, 已经被多方分析且广为全世界所使用高级加密标准已然成为对称密钥加密中最流行的算法之一
AES: 高级加密原理:
AES 是一个新的可以用于保护电子数据的加密算法明确地说, AES 是一个迭代的对称密钥分组的密码, 它可以使用 128192 和 256 位密钥, 并且用 128 位 (16 字节) 分组加密和解密数据与公共密钥密码使用密钥对不同, 对称密钥密码使用相同的密钥加密和解密数据通过分组密码返回的加密数据 的位数与输入数据相同迭代加密使用一个循环结构, 在该循环中重复置换 (permutations ) 和替换 (substitutions) 输入数据 Figure 1 显示了 AES 用 192 位密钥对一个 16 位字节数据块进行加密和解密的情形
MD5:Message-Digest Algorithm 5(信息 - 摘要算法 5), 用于确保信息传输完整一致是计算机广泛使用的杂凑算法之一(又译摘要算法哈希算法), 主流编程语言普遍已有 MD5 实现这个应该是听到最多的算法, 据说是已经被破解了但是我觉得破解这个应该也要很久吧!
MD5 加密原理:
对 MD5 算法简要的叙述可以为: MD5 以 512 位分组来处理输入的信息, 且每一分组又被划分为 16 个 32 位子分组, 经过了一系列的处理后, 算法的输出由四个 32 位分组组成, 将这四个 32 位分组级联后将生成一个 128 位散列值
目前破解 MD5 主要依靠大型字典的方法, 将常用密码进行 MD5 后建立数据库, 然后和 MD5 数值进行对比, 通过这样的方法来破解 MD5, 因此, 通常直接将密码进行 MD5 处理的话,
一些弱密码很容易可以通过这种手段破解出 来不过, 如果在散列的过程中, 加入足够长的 salt(即干扰字符串), 并且 salt 加入一些动态信息, 例如 username 随机码等,
这样生成的 MD5 还是很难被破解的, 因为仅仅从数据库无法看到 MD5 具体的处理过程, 必须同时看到处理时的源代码才可以, 这就给破解 MD5 带来相当大的难度
Base64:Base64 是网络上最常见的用于传输 8Bit 字节代码的编码方式之一 Base64 编码可用于在 HTTP 环境下传递较长的标识信息例如, 在 Java Persistence 系统 Hibernate 中, 就采用了 Base64 来将一个较长的唯一 标识符 (一般为 128-bit 的 UUID) 编码为一个字符串, 用作 HTTP 表单和 HTTP GET URL 中的参数在其应用程序中, 也常常需要把二进制数据编码为适合放在 URL(包括隐藏表单域)中的形式此时, 采用 Base64 编码具有不可读性, 即所编码的数据不会被人用肉眼所直接看到
RSA 加密方式:
RSA 加密方式相信每一个对接过支付宝 SDK 的同学都听过这个 RSA 加密, 因为支付宝 SDK 的加密方式采用的就是这种
它的一个大致额历程是这样:
1 生成你的公钥给支付宝, 注册支付宝 SDK 之后你也可以拿到支付宝公钥
2 上传你的公钥到支付宝, 用你的私钥加密你的信息, 支付包用你上传的公钥解密你传给支付宝的信息
3 用你拿到的支付宝的公钥解密支付宝回调给你的信息
注意: 不要把这新秘钥信息存放在客户端, 存放在服务端也建议不要使用明文的形式存储, 安全问题! 有些说把秘钥制作成. a 文件的形式存放的客户端, 问题反编译之后直接拿到你这份. a 文件是不是也可以用用呢?
RSA 是目前最有影响力的公钥加密算法, 该算法基于一个十分简单的数论事实: 将两个大素数相乘十分容易, 但那时想要对其乘积进行因式分解却极其困难,
因此可以将乘积公开作为加密密钥, 即公钥, 而两个大素数组合成私钥公钥是可发布的供任何人使用, 私钥则为自己所有, 供解密之用
加密模式
我们通过下面的两张图解释一下这俩种加密模式, 因为在后面的代码解读中我们会涉及到这一点, 要是不了解后面代码中有些点可能会犯迷糊:
ECB: 电子密码本, 就是每个块都是独立加密的
CBC: 密码块链, 使用一个密钥和一个初始化向量 (IV) 对数据执行加密转换
重点说说它们的代码部分
(首先说明 DES 由于自身的缺陷, 就不再去研究看它的代码了, 我们这里研究的也不会特别深, 主要是为了在项目中的使用)
先说说这个类: CCCryptorStatus
关于 CCCryptorStatus, 构造它可以使用 CCCrypt
CCCryptorCreateWithMode
CCCryptorCreate 等好多类构造, 在使用这些类构造时对参数是比较多, 我们看着它们的头文件, 解读一下参数的含义, 我们就用 CCCrypt 为例说明一下, 下面是 CCCrypt 的结构代码:
- 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)
- __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
理解了它的参数在我们写 AES 加密代码的时候是有很大的帮助的, 下面是它的头文件中 Apple 给的参数解释, 我们解释一下:
- // 设置加密参数
- /*!
- @function CCCrypt
- @abstract Stateless, one-shot encrypt or decrypt operation.
- This basically performs a sequence of CCCrytorCreate(),
- CCCryptorUpdate(), CCCryptorFinal(), and CCCryptorRelease().
- @param alg Defines the encryption algorithm. 定义加密的算法
- alg:
- enum {
- kCCAlgorithmAES128 = 0,
- kCCAlgorithmAES = 0,
- kCCAlgorithmDES,
- kCCAlgorithm3DES,
- kCCAlgorithmCAST,
- kCCAlgorithmRC4,
- kCCAlgorithmRC2,
- kCCAlgorithmBlowfish
- };
- @param op Defines the basic operation: kCCEncrypt or kCCDecrypt. 定义加密还是解密
- 下面是补码方式
- enum {
- kCCOptionPKCS7Padding = 0x0001,
- kCCOptionECBMode = 0x0002};
- @param options A word of flags defining options. See discussion for the CCOptions type.
- // 加密的 key
- @param key Raw key material, length keyLength bytes.
- // 加密的 key 的长度
- @param keyLength Length of key material. Must be appropriate for the select algorithm. Some algorithms may
- provide for varying key lengths.
- // IV 向量
- @param iv Initialization vector, optional. Used for
- Cipher Block Chaining (CBC) mode. If present,
- must be the same length as the selected
- algorithm's block size. If CBC mode is
- selected (by the absence of any mode bits in
- the options flags) and no IV is present, a
- NULL (all zeroes) IV will be used. This is
- ignored if ECB mode is used or if a stream
- cipher algorithm is selected. For sound encryption,
- always initialize IV with random data.
- IV 向量: 大概意思说, 此属性可选, 但只能用于 CBC 模式
- 如果出现那么他的长度必须和算法的 block size 保持一致
- 如果是因为默认选择的 CBC 模式而且向量没有定义, 那么向量会被定义为 NULL
- 如果选择了 ECB 模式或是其他的流密码算法, 之前所说的逻辑都不成立
- NOTE**** 如果你想使用密钥偏移量 IV 那你的加密模式必须为 CBC, 不能使用别的模式
- // 需要加密或者解密处理的 data 以及 data 的长度
- @param dataIn Data to encrypt or decrypt, length dataInLength bytes.
- @param dataInLength Length of data to encrypt or decrypt.
- // 加密或者解密后的数据会写在这个 data 中 以及它的长度
- @param dataOut Result is written here. Allocated by caller. Encryption and decryption can be performed "in-place",
- with the same buffer used for input and output.
- @param dataOutAvailable The size of the dataOut buffer in bytes.
- //
- @param dataOutMoved On successful return, the number of bytes written to dataOut.
- If kCCBufferTooSmall is returned as a result of insufficient buffer
- space being provided, the required buffer space is returned here.
- // 几种错误情况的说明
- @result kCCBufferTooSmall indicates insufficent space in the dataOut buffer.(表明 dataOut 的空间不足) In this case, the *dataOutMoved
- parameter will indicate the size of the buffer needed to complete the operation.
- The operation can be retried with minimal runtime penalty.
- kCCAlignmentError indicates that dataInLength was not properly
- aligned. This can only be returned for block
- ciphers, and then only when decrypting or when
- encrypting with block with padding disabled.
- kCCDecodeError Indicates improperly formatted ciphertext or a "wrong key" error; occurs only during decrypt operations.
- 我们可以通过下面的解释解读一下这个 result 具体的结果可以看下面的解释
- @enum CCCryptorStatus
- @abstract Return values from CommonCryptor operations.
- enum {
- kCCSuccess Operation completed normally.
- kCCParamError Illegal parameter value.
- kCCBufferTooSmall Insufficent buffer provided for specified operation.
- kCCMemoryFailure Memory allocation failure.
- kCCAlignmentError Input size was not aligned properly.
- kCCDecodeError Input data did not decode or decrypt properly.
- kCCUnimplemented Function not implemented for the current algorithm.
- }
- */
AES 加密代码
我们给出的就是具体的 AES 加密方式的代码, 涉及到的其他的 Base64 编码方式等等这些我们就不在专门去写代码, 这个在 Demo 中都有, 需要的建议去翻翻 Demo:
- - (NSData *)aes256_encrypt:(NSString *)key // 加密
- {
- // kCCKeySizeAES256 是加密位数
- /*
- 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,
- };
- */
- char keyPtr[kCCKeySizeAES256+1];
- bzero(keyPtr, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- //IV
- NSUInteger dataLength = [self length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void * buffer = malloc(bufferSize);
- size_t numBytesEncrypted = 0;
- CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- keyPtr, kCCBlockSizeAES128,
- NULL,
- [self bytes], dataLength,
- buffer, bufferSize,
- &numBytesEncrypted);
- if (cryptStatus == kCCSuccess) {
- return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
- }
- free(buffer);
- return nil;
- }
- -(NSData *)aes256_decrypt:(NSString *)key // 解密
- {
- //key 处理
- char keyPtr[kCCKeySizeAES256+1];
- bzero(keyPtr, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- /*IV
- char ivPtr[kCCBlockSizeAES128 + 1];
- bzero(ivPtr, sizeof(ivPtr));
- [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
*$/ 输出对象
- NSUInteger dataLength = [self length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- size_t numBytesDecrypted = 0;
- //kCCDecrypt 解密
- CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- keyPtr, kCCBlockSizeAES128,
- NULL,
- [self bytes], dataLength,
- buffer, bufferSize,
- &numBytesDecrypted);
- if (cryptStatus == kCCSuccess) {
- return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
- }
- free(buffer);
- return nil;
- }
最后:
针对 Base64 位的编码方式有的第三方比如: GTMBase64
或者是针对 DES 的第三方比如: SSkeychain
这些网上文章的确比较多了, 我们再总结也就没有了什么意义下面是我参考也是收集的一下关于加密算法的总结, 提供给大家
1iOS 各种加密 Base64 MD5 DES AES RSA
2 iOS 中使用 RSA 加密
3iOS 中的对称加密算法
来源: https://www.cnblogs.com/taoxu/p/8602334.html