欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IOS 常见加密算法

程序员文章站 2024-03-16 20:28:58
...

背景

粗略总结了下几个常用的加密算法,一为方便自己查阅,二为他人参考,如有很 low 或者错误的地方,还望指正
这里总结的算法有:Base64、MD5、SHA1、HMAC、AES 算法。
废话少说,开始:

一、 Base64

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一

/** Base64 加密 */
- (NSString *)Base64EnCrypt
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64String = [data base64EncodedStringWithOptions:0];
    
    NSLog(@"Base64加密:%@", base64String);
    
    return base64String;
}

/** Base64 解密 */
- (NSString *)Base64DeCrypt
{
    NSData *baseData = [[NSData alloc] initWithBase64EncodedString:self options:0];
    NSString *baseStr = [[NSString alloc] initWithData:baseData encoding:NSUTF8StringEncoding];
    
    NSLog(@"Base64解密:%@", baseStr);
    
    return baseStr;
}

二、MD5

MD5加密是最常用的加密方法之一,是从一段字符串中通过相应特征生成一段32位的数字字母混合码。
MD5主要特点是 不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样(也不是绝对的,但基本是不能一样的)。
MD5算法还具有以下性质:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
5、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。
MD5虽然说是不可逆的,但是由于有网站http://www.cmd5.com的存在,专门用来查询MD5码 所以有的简单的MD5码是可以在这里搜到源码的。为了让MD5码更加安全 涌现了很多其他方法 如加盐。 盐要足够长足够乱 得到的MD5码就很难查到。

/** MD5 加密 */
- (NSString *)MD5
{
    const char *str = self.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(str, (CC_LONG)strlen(str), buffer);
    
    NSLog(@"MD5加密:%@", [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]);
                        
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

三、 SHA

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
SHA1有如下特性:
不可以从消息摘要中复原信息;
两个不同的消息不会产生同样的消息摘要。

/** SHA1 加密 */
- (NSString *)SHA1
{
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(str, (CC_LONG)strlen(str), buffer);
    
    NSLog(@"SHA1:%@", [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH]);
    
    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}

/** SHA256 加密 */
- (NSString *)SHA256
{
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    
    NSLog(@"SHA256:%@", [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH]);
    
    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}

/** SHA512 加密 */
- (NSString *)SHA512
{
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(str, (CC_LONG)strlen(str), buffer);
    
    NSLog(@"SHA512:%@", [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH]);
    
    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}

四、HMAC

HMAC是**相关的哈希运算消息认证码,HMAC运算利用哈希算法,

  • 以一个**和一个消息为输入,生成一个消息摘要作为输出。
  • 作用:
    (1)验证TPM接受的授权数据和认证数据;
    (2)确认TPM接受到的命令请求是已授权的请求,并且,命令在传送的过程中没有被改动过。
- (NSString *)hmacMD5StringWithKey:(NSString *)key
{
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    NSLog(@"HMACMD5:%@", [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]);
    
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

/** hmacSHA1 加密 */
- (NSString *)hmacSHA1StringWithKey:(NSString *)key
{
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA1, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    NSLog(@"HMACSHA1:%@", [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]);

    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}

/** hmacSHA256 加密 */
- (NSString *)hmacSHA256StringWithKey:(NSString *)key
{
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA256, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    NSLog(@"HMACSHA256:%@", [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]);

    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}

/** hamcSHA512 */
- (NSString *)hmacSHA512StringWithKey:(NSString *)key
{
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA512, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    NSLog(@"HMACSHA512:%@", [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]);

    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}

五、AES 加密

#warning 注意:中文字符暂未处理好
#pragma mark - AES 加密与解密
/** AES256 加密 */
- (NSString *)AES256EnCrypt:(NSString *)key
{
    // 将字符串转化为 NSData 数据
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    //对数据进行加密
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSData *baseData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        
        if (baseData && baseData.length > 0) {
            Byte *datas = (Byte*)[baseData bytes];
            int length = (int)baseData.length;
            NSString *value = [self stringFromBytes:datas length:length];
            [value stringByRemovingPercentEncoding];
            NSLog(@"AES 加密:%@", value);
            
            return value;
        }
    }
    free(buffer);
    
    return nil;
}

/** AES256 解密 */
- (NSString *)AES256Decrypt:(NSString *)key
{
    //转换为2进制Data
    NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i = 0; i < [self length] / 2; i++) {
        byte_chars[0] = [self characterAtIndex:i*2];
        byte_chars[1] = [self characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
    }
    
    
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesDecrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *baseData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        
        if (baseData && baseData.length > 0) {
            NSString *value = [[NSString alloc] initWithData:baseData encoding:NSUTF8StringEncoding];
            NSLog(@"AES 解密:%@", value);
            
            return value;
        }
        
    }
    free(buffer);
    return nil;
}

参考资料

si1ence的简书:iOS常见的几种加密方法
*的博客:iOS开发之Objective-c的AES加密和解密算法的实现

Github 项目:EncryptionAlgorithm