9.加密

2021-11-17  本文已影响0人  LucXion

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字节,所以需要选择合适的模式。模式是一种算法,用于将数据分组串起来,使得任何数据都可以加密。

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

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

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

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

加密和压缩

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

上一篇 下一篇

猜你喜欢

热点阅读