IOS 常见加密算法
背景
粗略总结了下几个常用的加密算法,一为方便自己查阅,二为他人参考,如有很 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加密和解密算法的实现