iOS开发之算法加密md5,sha1,AES,base64

1. md5:

      MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。(引用自百度百科)

MD5加密目前来说是不可逆的,只能用作一些检验过程,不能恢复其原文。

      MD5算法产生的是固定的128bit,即128个0和1的二进制位,而在实际应用开发中,通常是以16进制输出的,所以正好就是32位的16进制数,说白了也就是32个16进制的数字。

需要引入头文件:

#import <CommonCrypto/CommonDigest.h>

#define CC_MD5_DIGEST_LENGTH    16          /* digest length in bytes */
复制代码
- (NSString *)md5:(NSDictionary *)paramsDict {
NSString *inString = [paramsDict stringValueForKey:@"data" defaultValue:@""];
    if (inString.length <= 0) {
        return @"";
    } else {
        const char *cStrValue = [inString UTF8String];
        //开辟一个16字节(128位:md5加密出来就是128位/bit)的空间(一个字节=8字位=8个二进制数)
        unsigned char outResult[CC_MD5_DIGEST_LENGTH];
        CC_MD5(cStrValue, strlen(cStrValue), outResult);
        
        //x表示十六进制,X  意思是不足两位将用0补齐,如果多余两位则不影响
        NSString *outString =
        [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
               outResult[0], outResult[1], outResult[2], outResult[3],
               outResult[4], outResult[5], outResult[6], outResult[7],
               outResult[8], outResult[9], outResult[10], outResult[11],
               outResult[12], outResult[13], outResult[14], outResult[15]];
        /*
        //方法二:
        NSMutableString *outString = [NSMutableString string];
        for (int i = 0; i < 16; i++) {
             [outString appendFormat:@"X", outResult[i]];
        }
        */
        return outString;
    }
 }
复制代码

     为什么是[16]呢,这是因为MD5算法最后生成的是128位,而在计算机的最小存储单位为字节,1个字节是8位,对应一个char类型,计算可得需要16个char。所以result是[16]。那么为什么输出的格式一定是%02x呢,而不是其它呢。这也是有原因的:因为约定MD5一般是以16进制的格式输出,那么其实这个问题就转换为把128个0和1以16进制来表示,每4位二进制对应一个16进制的元素,则需要32个16进制的元素,如果元素全部为0,放到char的数组中,正常是不会输出,如00001111,以%x输出,则是f,那么就会丢失0;但如果以%02x表示则输出结果是0f,正好是转换的正确结果。

 

2. sha1 加密

 SHA1 算法一样不可逆。

复制代码
- (NSString *) sha1:(NSString *)input
{
    const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:input.length];

    //#define CC_SHA1_DIGEST_LENGTH   20       /* digest length in bytes */
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, data.length, digest);
    
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    for(int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {
         [output appendFormat:@"%02x", digest[i]];
    }
    return output;
}
复制代码

 

3. AES 加密

高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法。

需要注意的是,AES并不能作为HASH算法,加密并解密后的结果,并不一定与原文相同,使用时请注意进行结果验算。例如解密原文的长度,格式规则等。

需要引入头文件

#import <CommonCrypto/CommonCryptor.h>

加密和解密方法使用的参数密钥可以均为32位长度的字符串,可以将任意的字符串经过md5计算32位字符串作为密钥,也可以自定义如:

#define APP_PUBLIC_PASSWORD     @"boundary"

复制代码
- (NSData *)AES256EncryptWithKey:(NSString *)key  withString:(NSString *) inputString { //加密
        NSData *inData = [inString dataUsingEncoding:NSUTF8StringEncoding];
        /***
        //如果希望返回字符串,在开始时就开始对 NSData 做转换, 对应下面方法三,方法一和二使用上面语句即可
        const char *cstr = [inString cStringUsingEncoding:NSUTF8StringEncoding];
        NSData *inData = [NSData dataWithBytes:cstr length:inString.length];
       ***/
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [APP_PUBLIC_PASSWORD getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [inData length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 
                                              kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              keyPtr, kCCBlockSizeAES128,
                                              NULL,
                                              [inData bytes], 
                                              dataLength,
                                              buffer, bufferSize,
                                              &numBytesEncrypted);


        if (cryptStatus == kCCSuccess) {
            NSData *outData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
            return outData;

           /***
             //如果需要返回 NSString 类型的结果,这里需要进行转换:
             // 方法一:
                 NSString *outString = [[NSString alloc]initWithData:outData encoding:NSUTF8StringEncoding];   
                 //失败,注意:这里 outString 为 nil,具体原因貌似是因为 NSData 内容含有非encoding编码的字符

             // 方法二:
                 NSString *outString = [outData base64Encoding];

             // 方法三:(转换为2进制字符串)
                 if (outData && outData.length > 0) {
                       Byte *datas = (Byte*)[outData bytes];
                       NSMutableString *outString = [NSMutableString stringWithCapacity:outData.length * 2];
                       for(int i = 0; i < outData.length; i++){
                             [outString appendFormat:@"%02x", datas[i]];
                       }
                  }
            ***/
        } 
        free(buffer);
        return nil;
}
复制代码
复制代码
//解密可以直接使用加密得到的结果 NSData, 这样将很容易,不必进行字符转换
- (NSData *)AES256DecryptWithKey:(NSString *)key withNSData:(NSString *)inData {//解密

/***
- (NSData *)AES256DecryptWithKey:(NSString *)key withString:(NSString *)inputString {//解密
        //对应加密算法中的方法二:(解密前进行GTMBase64编码)
           NSData *inData = [GTMBase64 decodeString:inString];
        //对应加密算法中的方法三:
           NSMutableData *inData = [NSMutableData dataWithCapacity:inString.length / 2];
           unsigned char whole_byte;
           char byte_chars[3] = {'\0','\0','\0'};
           int i;
           for (i=0; i < [inString length] / 2; i++) {
               byte_chars[0] = [inString characterAtIndex:i*2];
               byte_chars[1] = [inString characterAtIndex:i*2+1];
               whole_byte = strtol(byte_chars, NULL, 16);
               [inData appendBytes:&whole_byte length:1];
           }
 ***/     
   
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        //使用 "key": #define APP_PUBLIC_PASSWORD     @"boundary"
        [APP_PUBLIC_PASSWORD getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [inData length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,          
                                 kCCAlgorithmAES128,
                                 kCCOptionPKCS7Padding | kCCOptionECBMode,
                                 keyPtr, kCCBlockSizeAES128,
                                 NULL,
                                 [inData bytes], dataLength,
                                 buffer, bufferSize,
                                 &numBytesDecrypted);

        if (cryptStatus == kCCSuccess) {
            NSData *outData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
            return outData;
            /***
            //若需返回 NSString,需要上面加密算法和解密算法的各个方法对应好,使用下列语句才不会返回 nil; 切记 dataLength 一定匹配好
            NSString *outString = [[NSString alloc]initWithData:outData encoding:NSUTF8StringEncoding];
            ***/
        }
        free(buffer);
        return nil;
}
复制代码

 

4. base 64 加密算法

下载库 GTMBase64

 

实例demo:

http://up.2cto.com/2012/1215/20121215123257741.zip
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值