iOS常用加密算法介绍和代码实践

2020-01-15 18:28:00丽君

iOS系统库中定义了软件开发中常用的加解密算法,接口为C语言形式。具体包括了以下几个大类: 


 #include <CommonCrypto/CommonCryptor.h>  //常用加解密算法
 #include <CommonCrypto/CommonDigest.h>  //摘要算法
 #include <CommonCrypto/CommonHMAC.h>
 #include <CommonCrypto/CommonKeyDerivation.h>
 #include <CommonCrypto/CommonSymmetricKeywrap.h> 

其中第一类常用加解密算法就包含了AES,DES,和已经废弃的RC4,第二类摘要算法,包括如MD5,SHA等。本文主要介绍AES,MD5,SHA三种最常用算法的实现。
1 对称密码算法--AES
AES主要应用在关键数据和文件的的保密同时又需要解密的情形,其加密密钥和解密密钥相同,根据密钥长度分为128、192和256三种级别,密钥长度越大安全性也就越大,但性能也就越低,根据实际业务的安全要求来决定就好。通常情况,对一些关键数据进行加密的对象都是字符串,加密结果也以字符串进行保存,所以在设计接口的时候参数和返回值均为字符串。(关于关键参数的意义放在代码后讲解。)

1.1 加密过程 


-(NSString *)aes256_encrypt:(NSString *)key
{
  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, kCCAlgorithmAES,
                     kCCOptionPKCS7Padding | kCCOptionECBMode,
                     keyPtr, kCCKeySizeAES256,
                     NULL,
                     [data bytes], dataLength,
                     buffer, bufferSize,
                     &numBytesEncrypted);
  if (cryptStatus == kCCSuccess)
  {
    NSData *result = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    //base64
    return [result base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
  }else
  {
    return nil;
  }
  
}

1.2 解密过程


-(NSString *)aes256_decrypt:(NSString *)key
{
  NSData *data = [[NSData alloc] initWithBase64EncodedData:[self dataUsingEncoding:NSASCIIStringEncoding] options:NSDataBase64DecodingIgnoreUnknownCharacters];
  
  //对数据进行解密
  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, kCCAlgorithmAES,
                     kCCOptionPKCS7Padding | kCCOptionECBMode,
                     keyPtr, kCCKeySizeAES256,
                     NULL,
                     [data bytes], dataLength,
                     buffer, bufferSize,
                     &numBytesDecrypted);
  if (cryptStatus == kCCSuccess)
  {
    NSData* result = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    
  }else
  {
    return nil;
  }
  
}