谈谈iOS中的密码学(加密的一些措施)

对于我们iOS工作人员,在做登陆这块儿的时候,密码一定要进行加密,然后才进行网络请求,要不然就会被其他人获取用来做一些对我们不利的事情。

base64(可以反编译)

首先,我谈一下base64,有人说这是一个加密算法,可我觉得这更像是一个编码工具,因为它完全是可逆的,分分钟就会被破解,而且网络上有很多破解的工具,直接可以破解,所以这个一定不能用于密码的“加密”,一些不需要特别加密的,例如用户名,我们可以用base64进行编码,让人不是一眼就能看出来是什么。base64在iOS5之前没有直接集成的API,所以老的程序有可能用的是三方库,iOS5之后我们可以直接在工程中进行调用。下方是我对base64的详细说明:http://blog.csdn.net/liyunxiangrxm/article/details/52062009


md5(不可逆)

然后我们说说MD5,MD5是一个比较严密的加密方式,因为他是不可逆的。如果大家想要了解MD5的原理,请自行查询,我这里只介绍在咱们iOS中是如何用的。

如果想用MD5直接进行加密的:可以直接用以下代码返回即可

方法一、

#import 



@interface NSString (md5)

-(NSString *) md5HexDigest;

@end



#import "NSString+MD5HexDigest.h"

@implementation NSString (md5)

 

-(NSString *) md5HexDigest

{

   const char *original_str = [self UTF8String];

   unsigned char result[CC_MD5_DIGEST_LENGTH];

   CC_MD5(original_str, strlen(original_str), result);

   NSMutableString *hash = [NSMutableString string];

   for (int i = 0; i < 16; i++)

        [hash appendFormat:@"%02X", result[i]];

   return [hash lowercaseString];

}

 

@end



方法二、


将字符串进行MD5加密,返回加密后的字符串。
#import  // Need to import for CC_MD5 access
- (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
        @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
        result[0], result[1], result[2], result[3], 
        result[4], result[5], result[6], result[7],
        result[8], result[9], result[10], result[11],
        result[12], result[13], result[14], result[15]
        ]; 
}



1、当我们注册,登陆一套的时候,然后没有记住密码功能的,我们可以直接对密码进行MD5操作,注册的时候将MD5之后的密码传到服务端,服务端存储的是MD5之后的密码串,再次登陆的时候,客户端传过去MD5之后的密码与服务端存储的MD5后密码进行比对,当比对一样就返回成功,然后进行登陆。

    然而这样还是不够严密,因为网上有一套数据库http://cmd5.com可以查到许多MD5的词条,所以还是不够严密,这是我们可以用加盐的方式进行,加盐就是在原有的密码上再加上一段很长的字符,然后一起进行MD5操作,这就是加盐。

   这样还不够的话我们可以用HMAC +MD5的方式进行加密,(上方所说的方法已进行封装,可以直接用https://github.com/liyuunxiangGit/Security),然后还可以再加盐。方法 很多,这里不一一介绍了,大家可以看我的github,对其进行研究。


2、当我们想有记住密码的操作的时候,base64太容易解,MD5不可逆,如果存到用户中心的话很容易被取到,所以这是我想到的是用密码串,这个也已经封装好(网上应该有现成的三方库)我这里的https://github.com/liyuunxiangGit/Security/tree/master/%E9%92%A5%E5%8C%99%E4%B8%B2%E4%B8%89%E6%96%B9/SSKeychain


没有太详细的讲解,只是给大家一个思路。大家可以一起进行研究。


下方是从网上找了一张加密的图:大家可以看看

谈谈iOS中的密码学(加密的一些措施)_第1张图片



AES(可以反编译)

3、(文件加密)我之前还用到AES/CBC/PKCS5Padding 128位加密算法,加密后在BASE64编码。请求采用参数加密原则(json结构保留),结果采用整体加密原则(纯密文,解析完是json)。这里有找到的封装的方法可以一起研究:https://github.com/liyuunxiangGit/Security

下方是256位的封装的aes加密。

高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法。 以下实现代码中分别为NSData和NSString增加了一个Category。使用时直接调用即可。 

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

Objective-c的AES加密和解密算法的具体实现代码如下: 1.拓展NSData,增加AES256加密方法

//
//NSData+AES256.h
//
 
#import 
#import 
#import 
 
@interface NSData(AES256)
-(NSData *) aes256_encrypt:(NSString *)key;
-(NSData *) aes256_decrypt:(NSString *)key;
@end
 
 
//
//NSData+AES256.m
//
#import "NSData+AES256.h"
 
@implementation NSData(AES256)
 
- (NSData *)aes256_encrypt:(NSString *)key   //加密
{
  char keyPtr[kCCKeySizeAES256+1];
  bzero(keyPtr, sizeof(keyPtr));
  [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
  NSUInteger dataLength = [self length];
  size_t bufferSize = dataLength + kCCBlockSizeAES128;
  void *buffer = malloc(bufferSize);
  size_t numBytesEncrypted = 0;
  CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                      kCCOptionPKCS7Padding | kCCOptionECBMode,
                      keyPtr, kCCBlockSizeAES128,
                      NULL,
                      [self bytes], dataLength,
                      buffer, bufferSize,
                      &numBytesEncrypted);
  if (cryptStatus == kCCSuccess) {
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
  }
  free(buffer);
  return nil;
}
 
 
- (NSData *)aes256_decrypt:(NSString *)key   //解密
{
  char keyPtr[kCCKeySizeAES256+1];
  bzero(keyPtr, sizeof(keyPtr));
  [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
  NSUInteger dataLength = [self length];
  size_t bufferSize = dataLength + kCCBlockSizeAES128;
  void *buffer = malloc(bufferSize);
  size_t numBytesDecrypted = 0;
  CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                      kCCOptionPKCS7Padding | kCCOptionECBMode,
                      keyPtr, kCCBlockSizeAES128,
                      NULL,
                      [self bytes], dataLength,
                      buffer, bufferSize,
                      &numBytesDecrypted);
  if (cryptStatus == kCCSuccess) {
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
 
  }
  free(buffer);
  return nil;
}
@end

2.拓展NSString,增加AES256加密方法,需要导入NSData+AES256.h

//
//NSString +AES256.h
//
 
#import 
#import 
#import 
 
#import "NSData+AES256.h"
 
@interface NSString(AES256)
 
-(NSString *) aes256_encrypt:(NSString *)key;
-(NSString *) aes256_decrypt:(NSString *)key;
 
@end
 
 
//
//NSString +AES256.h
//
 
@implementation NSString(AES256)
 
-(NSString *) aes256_encrypt:(NSString *)key
{
  const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
  NSData *data = [NSData dataWithBytes:cstr length:self.length];
  //对数据进行加密
  NSData *result = [data aes256_encrypt:key];
 
  //转换为2进制字符串
  if (result && result.length > 0) {
 
    Byte *datas = (Byte*)[result bytes];
    NSMutableString *output = [NSMutableString stringWithCapacity:result.length * 2];
    for(int i = 0; i < result.length; i++){
      [output appendFormat:@"%02x", datas[i]];
    }
    return output;
  }
  return nil;
}
 
-(NSString *) aes256_decrypt:(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];
  }
 
  //对数据进行解密
  NSData* result = [data aes256_decrypt:key];
  if (result && result.length > 0) {
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]autorelease];
  }
  return nil;
}
@end


谈谈iOS中的密码学(加密的一些措施)_第2张图片

点击打开链接







你可能感兴趣的:(iOS,密码学,iOS研发进阶之路)