您的位置:首页 > 其它

加密算法(扩展知识:Base64编码)

2015-06-03 16:10 411 查看
在某些考虑数据安全的场景下,我们常常会用到加密解密、编码解码知识。比如把用户密码保存到数据库上,常用的方式是通过MD5或SHA1不可逆算法进行加密后密文保存。

这里主要介绍三种常用的加密算法:

(1)不可逆:MD5、SHA1

(2)可逆:AES256

另外常用的编码方式:

(1)可逆:Base64

main.m

//
//  main.m
//  OCEncryptionAlgorithm: UTF8String, cStringUsingEncoding, dataUsingEncoding, base64EncodedStringWithOptions, initWithBase64EncodedString, initWithData (加密算法)(扩展知识:Base64编码)
//
//  Created by Kenmu on 15/5/12.
//  Copyright (c) 2015年 Kenmu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "KMEncryption.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
//-------------------------MD5加密和SHA1加密
NSString *strSource = @"Kenmu-啊武";
NSLog(@"“%@”的MD5加密数据为:“%@”", strSource, [KMEncryption encryptByMD5:strSource]);

NSLog(@"“%@”的SHA1加密数据为:“%@”", strSource, [KMEncryption encryptBySHA1:strSource]);

//-------------------------AES256加密解密
NSString *strKey = @"12345678901234567890123456789012"; //strKey必须是32字节
NSData *data = [KMEncryption encryptByAES256:strSource withKey:strKey];
NSLog(@"“%@”的AES256加密数据为:“%@”", strSource, [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]);

strSource = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
data = [KMEncryption decryptByAES256:strSource withKey:strKey];
NSLog(@"“%@”的AES256解密数据为:“%@”", strSource, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

//-------------------------Base64编码解码
strSource = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"“%@”的Base64编码数据为:“%@”", strSource, [KMEncryption encodeBase64String:strSource]);

strSource = [KMEncryption encodeBase64String:strSource];
NSLog(@"“%@”的Base64解码数据为:“%@”", strSource, [KMEncryption decodeBase64String:strSource]);
}
return 0;
}


KMEncryption.h

#import <Foundation/Foundation.h>

@interface KMEncryption : NSObject
/**
*  MD5加密
*
*  @param strSource 需要被加密的明文字符串
*
*  @return MD5加密后的密文字符串
*/
+ (NSString *)encryptByMD5:(NSString *)strSource;

/**
*  SHA1加密
*
*  @param strSource 需要被加密的明文字符串
*
*  @return SHA1加密后的密文字符串
*/
+ (NSString *)encryptBySHA1:(NSString *)strSource;

/**
*  AES256加密
*
*  @param strSource 需要被加密的明文字符串
*  @param strKey    用于加密解密的32字节的密钥字符串(如不是32字节,就无法加密)
*
*  @return AES256加密后的密文字符串
*/
+ (NSData *)encryptByAES256:(NSString *)strSource withKey:(NSString *)strKey;

/**
*  AES256解密
*
*  @param strSource 需要被解密的密文字符串
*  @param strKey    用于加密解密的32字节的密钥字符串(如不是32字节,就无法解密)
*
*  @return AES256解密后的明文字符串
*/
+ (NSData *)decryptByAES256:(NSString *)strSource withKey:(NSString *)strKey;

/**
*  Base64编码
*
*  @param strSource 需要被编码的字符串
*
*  @return Base64编码后的字符串
*/
+ (NSString *)encodeBase64String:(NSString *)strSource;

/**
*  Base64解码
*
*  @param strSource 需要被解码的字符串
*
*  @return Base64解码后的字符串
*/
+ (NSString *)decodeBase64String:(NSString *)strSource;

@end


KMEncryption.m

//
//  KMEncryption.m
//  OCEncryptionAlgorithm
//
//  Created by Kenmu on 15/5/12.
//  Copyright (c) 2015年 Kenmu. All rights reserved.
//

#import "KMEncryption.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

@implementation KMEncryption

typedef NS_ENUM(NSUInteger, EncryptType) {
MD5,
SHA1
};

#pragma mark - 私有方法
/**
*  MD5或SHA1加密
*
*  @param strSource   需要被加密的明文字符串
*  @param encryptType 加密类型;例如:MD5、SHA1
*
*  @return 加密后的密文字符串
*/
+ (NSString *)encrypt:(NSString *)strSource encryptType:(EncryptType)encryptType {
NSString *strResult = nil;
const char *cSource = [strSource UTF8String]; //等同于[strSource cStringUsingEncoding:NSUTF8StringEncoding]
CC_LONG cSourceLen = (CC_LONG)strlen(cSource);
NSUInteger digestLen = 16;
unsigned char arrOutputDigest[digestLen];

switch (encryptType) {
case MD5: {
CC_MD5(cSource, cSourceLen, arrOutputDigest);
break;
}
case SHA1: {
CC_SHA1(cSource, cSourceLen, arrOutputDigest);
break;
}
default: {
break;
}
}

NSMutableString *mStrResult = [[NSMutableString alloc] init];
for (NSUInteger i=0; i<digestLen; i++) {
[mStrResult appendFormat:@"%02x", arrOutputDigest[i]]; //每个字符数组元素以(不足2位就补0的)16进制输出,16*2=32位
}
strResult = mStrResult;
return strResult;
}

/**
*  AES256加密解密
*
*  @param data      需要被加密解密的数据
*  @param strKey    用于加密解密的32字节的密钥字符串(如不是32字节,就无法解密)
*  @param isEncrypt 是否加密操作;YES为加密,NO为解密
*
*  @return AES256加密解密后的数据
*/
+ (NSData *)operationByAES256:(NSData *)data withKey:(NSString *)strKey isEncrypt:(BOOL)isEncrypt {
NSData *dataResult = nil;
NSUInteger dataLen = [data length];

char keyPtr[kCCKeySizeAES256+1]; //kCCKeySizeAES256=32
bzero(keyPtr, sizeof(keyPtr));
[strKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
size_t bufferSize = dataLen + kCCBlockSizeAES128; //kCCBlockSizeAES128=16;//对于块加密算法,输出大小总是等于或小于输入大小加上一个块的大小,所以在下边需要再加上一个块的大小
void *buffer = malloc(bufferSize);
size_t numBytesOperated = 0;
CCCryptorStatus cryptStatus = CCCrypt(isEncrypt ? kCCEncrypt : kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[data bytes], dataLen, //输入
buffer, bufferSize, //输出
&numBytesOperated);
if (cryptStatus == kCCSuccess) {
dataResult = [NSData dataWithBytesNoCopy:buffer length:numBytesOperated];
}
return dataResult;
}

#pragma mark - 公开方法
+ (NSString *)encryptByMD5:(NSString *)strSource {
NSString *strResult = nil;
if (strSource && strSource.length > 0) {
strResult = [self encrypt:strSource encryptType:MD5];
}
return strResult;
}

+ (NSString *)encryptBySHA1:(NSString *)strSource {
NSString *strResult = nil;
if (strSource && strSource.length > 0) {
strResult = [self encrypt:strSource encryptType:SHA1];
}
return strResult;
}

+ (NSData *)encryptByAES256:(NSString *)strSource withKey:(NSString *)strKey {
NSData *dataResult = nil;
if (strSource && strSource.length > 0 && strKey && strKey.length == 32) {
dataResult = [strSource dataUsingEncoding:NSUTF8StringEncoding]; //编码
dataResult = [self operationByAES256:dataResult
withKey:strKey
isEncrypt:YES];
}
return dataResult;
}

+ (NSData *)decryptByAES256:(NSString *)strSource withKey:(NSString *)strKey {
NSData *dataResult = nil;
if (strSource && strSource.length > 0 && strKey && strKey.length == 32) {
dataResult = [[NSData alloc] initWithBase64EncodedString:strSource
options:NSDataBase64DecodingIgnoreUnknownCharacters]; //解码
dataResult = [self operationByAES256:dataResult
withKey:strKey
isEncrypt:NO];
}
return dataResult;
}

+ (NSString *)encodeBase64String:(NSString *)strSource {
NSData *data = [strSource dataUsingEncoding:NSUTF8StringEncoding];
return [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}

+ (NSString *)decodeBase64String:(NSString *)strSource {
NSData *data = [[NSData alloc] initWithBase64EncodedString:strSource
options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

@end


结果:

2015-05-14 00:21:36.203 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的MD5加密数据为:“d33ee89d8ea08c8d258df20b7836bd02”
2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的SHA1加密数据为:“9bb7a793756842e38a76815bb03dd968”
2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的AES256加密数据为:“1KQQ/bVAkRszh8Ue18VzMQ==”
2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “1KQQ/bVAkRszh8Ue18VzMQ==”的AES256解密数据为:“Kenmu-啊武”
2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的Base64编码数据为:“S2VubXUt5ZWK5q2m”
2015-05-14 00:21:36.205 OCEncryptionAlgorithm[1010:79295] “S2VubXUt5ZWK5q2m”的Base64解码数据为:“Kenmu-啊武”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: