9.加密

作者: LucXion | 来源:发表于2021-11-17 10:55 被阅读0次

AES 高级加密算法

  • 对称加密
  • 提供三种秘钥长度,128位,192位,256位,除非有特殊需要,一般推荐使用128位,在安全和性能之间有很好的平衡
  • AES 只是一个接收固定长度秘钥和16字节大小的分组,然后生成另外一个16字节大小的分组的数学函数。
  • AES 没有提供认证机制来处理对密文的意外或故意损坏。但可以为AES 添加差错校验。

如何将密码转化为秘钥,PBKDF2:生成一个很大的随机数(盐),标准推荐最少达到64位,盐和密码将会搭配使用来阻止相同密码生成相同秘钥。循环执行PBKDF2若干次,最终的数据就是你的秘钥。这个过程称为扩展,要解密数据,只需要保留盐和循环次数。

#import <CommonCrypto/CommonKeyDerivation.h>
#import "RNCryptor/RNCryptor.h"  

NSData *salt = [self randomDataOfLenght:8];

- (NSData *)randomDataOfLenght:(size_t)length {
    NSMutableData *data = [NSMutableData dataWithLength:length];
    int result = SecRandomCopyBytes(kSecRandomDefault, length, data.mutableBytes);
    NSAssert(result == 0, @"Unable to generate random bytes:%d",errno);
    return data;
}

/*
 struct _RNCryptorKeyDerivationSettings
 {
   size_t keySize;
   size_t saltSize;
   uint32_t PBKDFAlgorithm;(CCPBKDFAlgorithm,SHA256通常会是倾向的选择,它是特定大小的SHA-2)
   uint32_t PRF;(CCPseudoRandomAlgorithm,伪随机函数,用来生成很长的统计上随机的一系列数)
   uint rounds;
   BOOL hasV2Password; // See Issue #77. V2 incorrectly handled multi-byte characters.
 } RNCryptorKeyDerivationSettings;
 */
// 生成秘钥,盐和循环次数必须和密文存储到一起
+ (NSData *)keyForPassword:(NSString*)password salt:(NSData *)salt settings:(RNCryptorKeyDerivationSettings)keySettings {
    
    NSMutableData *derivedKey = [NSMutableData dataWithLength:keySettings.keySize];
    size_t passwordLength = [password lengthOfBytesUsingEncoding:kCFStringEncodingUTF8];

    int result = CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm, password.UTF8String, password.length, salt.bytes, salt.length, keySettings.PRF, keySettings.rounds, derivedKey.mutableBytes, derivedKey.length);
    
    NSAssert(result == 0, @"Unable to generate random bytes:%d",errno);
    
    return derivedKey;
}

AES 模式和填充

AES一次处理128位的输入数据,但大多数需要加密的数据都不是16字节,所以需要选择合适的模式。模式是一种算法,用于将数据分组串起来,使得任何数据都可以加密。

  • EBC:最简单的模式,电子密码本,适用于加密大量随机分组的情况,一般不予考虑,如果两个普通文本分组一样,生成的密文就会完全相同,不够安全。
  • CBC:密码分组链模式,每个分组的密文都会同下一个未加密的普通文本分组进行异或运算。缺点是加密过程无法并行,并且普通文本必须是分组大小(16字节)的整数倍(可以通过填充来实现)。

填充:iOS唯一支持的填充方式,PKCS #7(kCCOptionPKCS7Padding),会在源数据后面追加n个值为n的字节,如果数据分组刚好匹配,那么会追加整个分组的0x10,这意味着密文可能比普通文本多出一个分组。有一种称作密文盗用(ciphertext stealing)的方法跟CBC兼容,但iOS只支持CBC。

如果面临无法使用填充的情况,推荐使用密码反馈(Cipher Feedback, CFB)、输出反馈(Output Feedback OFB)

如果需要避免初始化向量的开销,计数器(Count,CTR)模式会比较有用

XTS是针对随机访问数据的一个特定模式,尤其是在加密的文件系统上

加密和压缩

加密数据前先压缩一下数据,可以让数据变得更小。记住必须在加密前压缩,不能加密压缩过的数据,如果你能把加密过的数据压缩的更小,那就意味着密文中有重复的片段,着又说明加密的算法不够强大。大多数情况下,加密后的数据压缩后比原始普通文本数据要大。

相关文章

网友评论

      本文标题:9.加密

      本文链接:https://www.haomeiwen.com/subject/uldltrtx.html