2014-12-09 15:09:46 zss_ing 阅读数 4320
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5955 人正在学习 去看看 李文瀚

       iOS app加密&探究爱加密iOS app加密原理。做安卓开发的一定都了解有爱加密安卓加密技术以及原理,不知道的我这里重新讲解下:

        常见的安卓加密方法有:伪加密、混淆保护、运行时验证、爱加密apk加密四个方法。在这里每个方法我就不详细说了,想了解的可以看下这篇大牛的博客:http://blog.csdn.net/chengyingzhilian/article/details/38372601

        爱加密安卓应用加密原理是通过对DEX源文件进行加壳保护,隐藏源代码;对资源文件,主配置文件进行指纹校验保护,来防止二次打包。废话不多说,今天是来研究爱加密iOS app加密原理的!

        虽说安卓是开源,iOS是闭源,但是都是代码,总是有相通之处的。所以我觉得黑客的破解技术也是类似的。那么,相对应的iOS app加密原理会不会也是相似的呢?楼主也是前段时间听说爱加密出了iOS app加密,出于好奇,在他们网站潜伏了好久,研究下来iOS app加密原理,给各位iOS app开发者一个参考。都说对症下药,iOS app加密肯定也是有针对性的,他们针对的就是iOS app存在的安全风险。首先,我们来了解下iOS app存在的安全风险

         iOS app存在的安全风险包括:

        1、内购破解

        插件法(仅越狱)、iTools工具替换文件法(常见为存档破解)、八门神器修改iOS app源代码

        2、网络安全风险

        截获网络请求,破解通信协议并模拟客户端登录,伪造用户行为,对iOS app用户数据造成危害

        3、应用程序函数PATCH破解

       利用FLEX 补丁软件通过派遣返回值来对iOS app进行patch破解

        4、源代码安全风险

        通过使用ida等反汇编工具对ipa进行逆向汇编代码,导致核心代码逻辑泄漏与被修改,影响iOS app安全

        爱加密iOS app加密是针对iOS的技术原理和破解原理,分别从本地数据、方法体/方法名、URL编码、程序结构、网络传输数据等几个方面对iOS app进行加密。下面是具体解析:

        1、本地数据加密

        iOS app加密技术一:对NSUserDefaultssqlite存储文件数据加密,保护帐号和关键信息

        2URL编码加密

       iOS app加密技术二:对程序中出现的URL进行编码加密,防止URL被静态分析

       3、网络传输数据加密

       iOS app加密技术三:对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取数据

        4、方法体,方法名高级混淆

        iOS app加密技术四:对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码

        5、程序结构混排加密

        iOS app加密技术五:对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

       下面是爱加密iOS app加密前后对比图

 

        虽说爱加密iOS app加密技术没有十分高深,但至少在国内填补了iOS app加密的空白!(支持国产啊)从去年开始,移动互联网圈内涌现了不少从事移动应用安全服务的公司,其中不乏互联网大佬,这些公司更多的重心一直都在安卓应用安全,提供的服务都是为安卓应用加密服务,没有对iOS app提供安全加密服务的公司。爱加密此举可谓全球首创,勇气可嘉!

        以上只是本人在爱加密体验的一把iOS app加密,有iOS app加密需求的小伙伴们请自行前往爱加密官网-iOS app加密页面,友情告知下地址:http://www.ijiami.cn/ios

 

2018-11-28 17:17:30 li897636595 阅读数 1039
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5955 人正在学习 去看看 李文瀚

1、创建类 SecurityUtility
2、.h文件代码:

#import <Foundation/Foundation.h>

@interface SecurityUtility : NSObject

//SHA256加密
+ (NSString*)sha256HashFor:(NSString *)input;

@end

3、.m文件代码:

#import "SecurityUtility.h"
#import <CommonCrypto/CommonDigest.h>

@implementation SecurityUtility

//SHA256加密
+ (NSString*)sha256HashFor:(NSString*)input{
    const char* str = [input UTF8String];
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(str, (CC_LONG)strlen(str), result);
    
    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
    for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
    {
        [ret appendFormat:@"%02x",result[i]];
    }
    ret = (NSMutableString *)[ret uppercaseString];
    return ret;
}
@end

4、测试

NSString *str = [SecurityUtility sha256HashFor:@"dashidahsidias"];
NSLog(@"str:%@", str);

5、测试结果

str:03D8540484EEC7519B1493776B5D4159AC7631E9A52769488F796C55A3FD9136
2015-12-21 11:00:48 werctzzz 阅读数 2000
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5955 人正在学习 去看看 李文瀚

最近技术群里看到了也有人在问关于iOS加密的问题,今天就顺便解答一下。

常用的是MD5加密,这是一种单向加密,实现如下:


需要添加的类库:
#import<CommonCrypto/CommonDigest.h>
#import<CommonCrypto/CommonCrypto.h>
#import<Foundation/Foundation.h>
#include<string.h>

MD5实现方法(16位):
+ (NSString *)md5:(NSString *)str
{
constchar *concat_str = [strUTF8String];
unsignedchar result[CC_MD5_DIGEST_LENGTH];
CC_MD5(concat_str, (unsignedint)strlen(concat_str), result);
NSMutableString *hash = [NSMutableStringstring];
for (int i =0; i <16; i++){
[hashappendFormat:@"%02X", result[i]];
}
return [hashuppercaseString];
}
还有就是base64的加密,这个加密在别的资源网站或是技术贴里面的描述的都一样,我们都需要去下载
提供使用的相关类,GTMBase64.zip库文件包,并解压,获得GTMBase64.h,GTMBase64.m和
GTMDefines.h三个文件。
下载地址是:https://github.com/r258833095/GTMBase64

新建一个base64的类,在base64.h中天假四个函数:
+ (NSString*)encodeBase64String:(NSString*)input;
+ (NSString*)decodeBase64String:(NSString*)input;
+ (NSString*)encodeBase64Data:(NSData*)data;
+ (NSString*)decodeBase64Data:(NSData*)data;

在base64.m文件中,实现上面4个函数:
+ (NSString*)encodeBase64String:(NSString* )input {
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64encodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
+ (NSString*)decodeBase64String:(NSString* )input {
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64decodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String
}
+ (NSString*)encodeBase64Data:(NSData*)data {
data = [GTMBase64encodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
+ (NSString*)decodeBase64Data:(NSData*)data {
data = [GTMBase64decodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
直接调用+ (NSString*)encodeBase64String:(NSString* )input和
+ (NSString*)decodeBase64String:(NSString* )input就可以进行加解密。

常用的AES加密,详解:

h文件内容:
#import 
@class NSString; 
@interface NSData (Encryption) 
- (NSData *)AESOverCycle:(NSString *)key; //加密 
- (NSData *)AESRelaes:(NSString *)key; //解密 
@end
m文件内容:
加密:
- (NSData *)AESOverCycle:(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 *)AESRelaes:(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;
} 



2015-12-23 10:26:14 CodingFire 阅读数 5510
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5955 人正在学习 去看看 李文瀚

**

关于iOS开发中使用到的AES加密和SHA256加密的使用

**
笔者在前段时间就这个问题跟后台的人对接了很久,最后终于确定问题是我们的加密方式虽然都为同一种,但却存在本质的区别。下面我简单描述下区别,并附上主要代码:
1. 常用AES加密说明
我们在开发中常用的AES为AES128和AES256,两者的区别在于256补码方式更加安全一点,按照一个字节为八位,采用的加密keyAES128为128/8=16位,AES256为256/8=32位,说到这里,需要注意一个参数:kCCOptionPKCS7Padding,这里java那里有多少种笔者没研究过,但是知道有另外一个叫:kCCOptionPKCS5Padding,但是iOS只有一种,也就是上面的所说的kCCOptionPKCS7Padding,那这怎么办呢?这里说下加密的key,这个参数跟加密key有关,上面有提到,AES128为16位加密key,AES256为32位加密key,正常来说,只要key满足这个要求,不管你用kCCOptionPKCS7Padding还是kCCOptionPKCS5Padding都是没区别的,但是当key少于这个数的时候,就需要进行补码了,这样区别就出来了,kCCOptionPKCS7Padding是缺几位,就补几个几,如:缺3位,补3个3,缺5位,补5个5,kCCOptionPKCS5Padding是缺几位就补几个0,如:缺3位,就补3个0.在使用中还有一个参数可以设置,iv向量,这个都是要自己设定的,也可不做设置,感兴趣的朋友可以自己去了解下iv向量,这里不做过多说明。
下面附上AES256和AES128加密代码片段供参考:

 - (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 *)AES128EncryptWithKey:(NSString *)key {//加密
    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCKeySizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) 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,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [self bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}

可以看到AES128有个iv向量,可手动设置。

2.下面来说下SHA256加密,这个相对于AES加密就简单很多了,百度上也有很多,但是笔者在使用的时候,从网上复制的代码,被坑的不轻,分明是SHA256,结果成了SHA的其他加密结果,看了下代码才知道原来网上的写错了,这里仅附上SHA256的代码,不多作说明。

//sha256加密方式
- (NSString *)getSha256String:(NSString *)srcString {
    const char *cstr = [srcString cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:srcString.length];

    uint8_t digest[CC_SHA256_DIGEST_LENGTH];

    CC_SHA256(data.bytes, data.length, digest);

    NSMutableString* result = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02x", digest[i]];
    }

    return result;
}

从上述代码可以看到里面有256字样,至于SHA的其他加密方式则是直接把参数替换为对应的数字就行了,有兴趣的朋友可以在使用中自己试试。
第一次发博客,有写的不好的,还请见谅。

2016-10-17 00:49:37 llyouss 阅读数 3450
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5955 人正在学习 去看看 李文瀚

分享源码,让苦逼的开发生活见鬼去。

     最近一直苦于开发,今天稍微有些时间,趁机先分享一下数据的加解密。后续补充用户数据的加密存储以及数据存储管理。

 1.AES加密(对称加密)

     特点:

     优点:简单、可并行计算、误差不传递

     缺点:不能隐藏明文模式(比如图像加密轮廓仍在)、主动攻击(改明文,后续内容不影响,只要误差不传递该缺点就存在)

     用途:需要并行加密的应用

    AES加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。AES加密算法被设计为支持128/192/256位(/32=nb)数据块大小(即分组长度);支持128/192/256位(/32=nk)密码长度,,在10进制里,对应34×1038、62×1057、1.1×1077个密钥

     AES加密的原理可以百度,这里就不详细说明了,下面进入开发正题

    NSData+AES.m 文件

//
//  NSData+AES.m
//  Encryption
//
//  Created by llyouss on 16/10/16.
//  Copyright © 2016年 llyouss. All rights reserved.
//

#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AES)

- (NSData *)AES256EncryptWithKey:(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 *)AES256DecryptWithKey:(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;
}

#import <CommonCrypto/CommonCryptor.h>
@end

   由于字符集冲突,我们先nsdata或base64位编码的形式存下来,否则会出现乱码。

调用事例

导入#import "SecurityUtil.h"

-(void)AESEncryption{
    NSString *testString = @"AESllyouss";
    NSLog(@"BASE64:%@", [SecurityUtil encodeBase64String:testString]);
    NSLog(@"MD5:%@", [SecurityUtil encryptMD5String:testString]);
    
    NSData *aesData = [SecurityUtil encryptAESData:testString];
    NSLog(@"AES加密:%@", aesData);
    NSLog(@"AES解密:%@", [SecurityUtil decryptAESData:aesData]);

}

2.DES加密(对称加密)


//des解密
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
    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, kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, kCCBlockSizeDES,
                                          NULL,
                                          [data bytes], dataLength,
                                          buffer, bufferSize,
                                          &numBytesDecrypted);
    
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer);
    return nil;
}
//des加密
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
    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, kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, kCCBlockSizeDES,
                                          NULL,
                                          [data bytes], dataLength,
                                          buffer, bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer);
    return nil;
}


3.BASE64编码

   其实base64编解码方式使用系统的api已经很方便,但是还是喜欢现成的。

    下载GTMBase64文件,在工程中加入三个文件
    GTMDefines.h
    GTMBase64.h
    GTMBase64.m
    下载地址:点击打开链接

    封装一下  

//
//  SecurityUtil.m
//  Encryption
//
//  Created by llyouss on 16/10/16.
//  Copyright © 2016年 llyouss. All rights reserved.
//

#import "SecurityUtil.h"
#import "GTMBase64.h"
#import "NSData+AES.h"
#import "NSString+MD5.h"

#define APP_PUBLIC_PASSWORD     @"boundary"
@implementation SecurityUtil

#pragma mark - base64
+ (NSString*)encodeBase64String:(NSString * )input {
    NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    data = [GTMBase64 encodeData:data];
    NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
    return base64String;
}

+ (NSString*)decodeBase64String:(NSString * )input {
    NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    data = [GTMBase64 decodeData:data];
    NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return base64String;
}

+ (NSString*)encodeBase64Data:(NSData *)data {
    data = [GTMBase64 encodeData:data];
    NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return base64String;
}

+ (NSString*)decodeBase64Data:(NSData *)data {
    data = [GTMBase64 decodeData:data];
    NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return base64String;
}
<span style="font-family:SimSun;">   </span>

4.MD5

  MD5是哈希算法,作用大家都应该知道,加密非常简单直接上方法

- (NSString *)md5Encrypt {
    
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, (int)strlen(cStr), result );
    NSMutableString *hash = [NSMutableString string];
    for (int i = 0; i < 16; i++)
        [hash appendFormat:@"%02X", result[i]];
    return [hash lowercaseString];
}

5.sha1&sha256加密

 MD5目前发现了重复,目前最新的是sha256,具体作用大家都应该知道。

//sha256加密方式
- (NSString *)Sha256String:(NSString *)srcString {
    const char *cstr = [srcString cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:srcString.length];

    uint8_t digest[CC_SHA256_DIGEST_LENGTH];

    CC_SHA256(data.bytes, data.length, digest);

    NSMutableString* result = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02x", digest[i]];
    }

    return result;
}
- (NSString *)sha1Encrypt{
    
    const char *cstr = [self UTF8String];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(data.bytes, (int)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;
}


6.RSA加密(非对称加密)

特点

RSA加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案之一。RSA是第一个能同时用于加密和数宇签名的算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA加密算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

 使用openssl实现,可以在这下载:点击打开链接

 1.生成RSA密钥
*  生成RSA私钥
    openssl genrsa -out rsa_private_key.pem 1024
* 生成RSA公钥
    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem    
    pem文件可以直接文本编辑器打开
    将RSA私钥转换成PKCS8格式
    openssl pkcs8 -topk8 -inform PEM -in private_rsa.pem -outform PEM -nocrypt -out private_key.pem (后边一定要加-out private_key.pem将转换后的私钥保存在private_key.pem,不然得到的结果要设置密码且显示在终端中,这个和得到pem中的私钥有差异。)

 2.导入OpenSSL,导入HBRSAHandler裤文件
  小技巧:记得在headSearchpath设置路径,不然编译报错。 

  HBRSAHandler.m 文件

 

//
//  HBRSAHandler.m
//  iOSRSAHandlerDemo
//
//  Created by wangfeng on 15/10/19.
//  Copyright (c) 2015年 HustBroventure. All rights reserved.
//
#import "HBRSAHandler.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/md5.h>

typedef enum {
    RSA_PADDING_TYPE_NONE       = RSA_NO_PADDING,
    RSA_PADDING_TYPE_PKCS1      = RSA_PKCS1_PADDING,
    RSA_PADDING_TYPE_SSLV23     = RSA_SSLV23_PADDING
}RSA_PADDING_TYPE;

#define  PADDING   RSA_PADDING_TYPE_PKCS1

@implementation HBRSAHandler
{

    RSA* _rsa_pub;
    RSA* _rsa_pri;
}
#pragma mark - public methord
-(BOOL)importKeyWithType:(KeyType)type andPath:(NSString *)path
{
    BOOL status = NO;
    const char* cPath = [path cStringUsingEncoding:NSUTF8StringEncoding];
    FILE* file = fopen(cPath, "rb");
    if (!file) {
        return status;
    }
    if (type == KeyTypePublic) {
        _rsa_pub = NULL;
        if((_rsa_pub = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL))){
            status = YES;
        }
        
        
    }else if(type == KeyTypePrivate){
        _rsa_pri = NULL;
        if ((_rsa_pri = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL))) {
            status = YES;
        }

    }
    fclose(file);
    return status;

}
- (BOOL)importKeyWithType:(KeyType)type andkeyString:(NSString *)keyString
{
    if (!keyString) {
        return NO;
    }
    BOOL status = NO;
    BIO *bio = NULL;
    RSA *rsa = NULL;
    bio = BIO_new(BIO_s_file());
    NSString* temPath = NSTemporaryDirectory();
    NSString* rsaFilePath = [temPath stringByAppendingPathComponent:@"RSAKEY"];
    NSString* formatRSAKeyString = [self formatRSAKeyWithKeyString:keyString andKeytype:type];
    BOOL writeSuccess = [formatRSAKeyString writeToFile:rsaFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    if (!writeSuccess) {
        return NO;
    }
    const char* cPath = [rsaFilePath cStringUsingEncoding:NSUTF8StringEncoding];
    BIO_read_filename(bio, cPath);
    if (type == KeyTypePrivate) {
        rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, "");
        _rsa_pri = rsa;
        if (rsa != NULL && 1 == RSA_check_key(rsa)) {
            status = YES;
        } else {
            status = NO;
        }


    }
    else{
        rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
        _rsa_pub = rsa;
        if (rsa != NULL) {
            status = YES;
        } else {
            status = NO;
        }
    }
    
           BIO_free_all(bio);
    [[NSFileManager defaultManager] removeItemAtPath:rsaFilePath error:nil];
    return status;
}


#pragma mark RSA sha1验证签名
    //signString为base64字符串
- (BOOL)verifyString:(NSString *)string withSign:(NSString *)signString
{
    if (!_rsa_pub) {
        NSLog(@"please import public key first");
        return NO;
    }

    const char *message = [string cStringUsingEncoding:NSUTF8StringEncoding];
    int messageLength = (int)[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSData *signatureData = [[NSData alloc]initWithBase64EncodedString:signString options:0];
    unsigned char *sig = (unsigned char *)[signatureData bytes];
    unsigned int sig_len = (int)[signatureData length];
    

    
   
    unsigned char sha1[20];
    SHA1((unsigned char *)message, messageLength, sha1);
       int verify_ok = RSA_verify(NID_sha1
                                      , sha1, 20
                                      , sig, sig_len
                                      , _rsa_pub);

    if (1 == verify_ok){
        return   YES;
    }
    return NO;
    
    
}
#pragma mark RSA MD5 验证签名
- (BOOL)verifyMD5String:(NSString *)string withSign:(NSString *)signString
{
    if (!_rsa_pub) {
        NSLog(@"please import public key first");
        return NO;
    }

    const char *message = [string cStringUsingEncoding:NSUTF8StringEncoding];
        // int messageLength = (int)[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSData *signatureData = [[NSData alloc]initWithBase64EncodedString:signString options:0];
    unsigned char *sig = (unsigned char *)[signatureData bytes];
    unsigned int sig_len = (int)[signatureData length];
    
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, message, strlen(message));
    MD5_Final(digest, &ctx);
    int verify_ok = RSA_verify(NID_md5
                                      , digest, MD5_DIGEST_LENGTH
                                      , sig, sig_len
                                      , _rsa_pub);
    if (1 == verify_ok){
        return   YES;
    }
    return NO;
    
}

- (NSString *)signString:(NSString *)string
{
    if (!_rsa_pri) {
        NSLog(@"please import private key first");
        return nil;
    }
    const char *message = [string cStringUsingEncoding:NSUTF8StringEncoding];
    int messageLength = (int)strlen(message);
    unsigned char *sig = (unsigned char *)malloc(256);
    unsigned int sig_len;
    
    unsigned char sha1[20];
    SHA1((unsigned char *)message, messageLength, sha1);
    
    int rsa_sign_valid = RSA_sign(NID_sha1
                                          , sha1, 20
                                          , sig, &sig_len
                                          , _rsa_pri);
    if (rsa_sign_valid == 1) {
        NSData* data = [NSData dataWithBytes:sig length:sig_len];
        
        NSString * base64String = [data base64EncodedStringWithOptions:0];
        free(sig);
        return base64String;
    }
    
    free(sig);
    return nil;
}
- (NSString *)signMD5String:(NSString *)string
{
    if (!_rsa_pri) {
        NSLog(@"please import private key first");
        return nil;
    }
    const char *message = [string cStringUsingEncoding:NSUTF8StringEncoding];
        //int messageLength = (int)strlen(message);
    unsigned char *sig = (unsigned char *)malloc(256);
    unsigned int sig_len;
    
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, message, strlen(message));
    MD5_Final(digest, &ctx);
    
    int rsa_sign_valid = RSA_sign(NID_md5
                                  , digest, MD5_DIGEST_LENGTH
                                  , sig, &sig_len
                                  , _rsa_pri);
   
    if (rsa_sign_valid == 1) {
        NSData* data = [NSData dataWithBytes:sig length:sig_len];
        
        NSString * base64String = [data base64EncodedStringWithOptions:0];
        free(sig);
        return base64String;
    }
    
    free(sig);
    return nil;

    
}

- (NSString *) encryptWithPublicKey:(NSString*)content
{
    if (!_rsa_pub) {
        NSLog(@"please import public key first");
        return nil;
    }
    int status;
    int length  = (int)[content length];
    unsigned char input[length + 1];
    bzero(input, length + 1);
    int i = 0;
    for (; i < length; i++)
        {
        input[i] = [content characterAtIndex:i];
        }
    
    NSInteger  flen = [self getBlockSizeWithRSA_PADDING_TYPE:PADDING andRSA:_rsa_pub];
    
    char *encData = (char*)malloc(flen);
    bzero(encData, flen);
    status = RSA_public_encrypt(length, (unsigned char*)input, (unsigned char*)encData, _rsa_pub, PADDING);
    
    if (status){
        NSData *returnData = [NSData dataWithBytes:encData length:status];
        free(encData);
        encData = NULL;
        
            //NSString *ret = [returnData base64EncodedString];
        NSString *ret = [returnData base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];
        return ret;
        }
    
    free(encData);
    encData = NULL;
    
    return nil;
}

- (NSString *) decryptWithPrivatecKey:(NSString*)content
{
    if (!_rsa_pri) {
        NSLog(@"please import private key first");
        return nil;
    }    int status;
    
        //NSData *data = [content base64DecodedData];
    NSData *data = [[NSData alloc]initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
    int length = (int)[data length];
    
    NSInteger flen = [self getBlockSizeWithRSA_PADDING_TYPE:PADDING andRSA:_rsa_pri];
    char *decData = (char*)malloc(flen);
    bzero(decData, flen);
    
    status = RSA_private_decrypt(length, (unsigned char*)[data bytes], (unsigned char*)decData, _rsa_pri, PADDING);
   
    if (status)
        {
        NSMutableString *decryptString = [[NSMutableString alloc] initWithBytes:decData length:strlen(decData) encoding:NSASCIIStringEncoding];
        free(decData);
        decData = NULL;
        
        return decryptString;
        }
    
    free(decData);
    decData = NULL;
    
    return nil;
}

- (int)getBlockSizeWithRSA_PADDING_TYPE:(RSA_PADDING_TYPE)padding_type andRSA:(RSA*)rsa
{
    int len = RSA_size(rsa);
    
    if (padding_type == RSA_PADDING_TYPE_PKCS1 || padding_type == RSA_PADDING_TYPE_SSLV23) {
        len -= 11;
    }
    
    return len;
}

-(NSString*)formatRSAKeyWithKeyString:(NSString*)keyString andKeytype:(KeyType)type
{
    NSInteger lineNum = -1;
    NSMutableString *result = [NSMutableString string];
    
    if (type == KeyTypePrivate) {
        [result appendString:@"-----BEGIN PRIVATE KEY-----\n"];
        lineNum = 79;
    }else if(type == KeyTypePublic){
    [result appendString:@"-----BEGIN PUBLIC KEY-----\n"];
         lineNum = 76;
    }
   
    int count = 0;
    for (int i = 0; i < [keyString length]; ++i) {
        unichar c = [keyString characterAtIndex:i];
        if (c == '\n' || c == '\r') {
            continue;
        }
        [result appendFormat:@"%c", c];
        if (++count == lineNum) {
            [result appendString:@"\n"];
            count = 0;
        }
    }
    if (type == KeyTypePrivate) {
        [result appendString:@"\n-----END PRIVATE KEY-----"];
       
    }else if(type == KeyTypePublic){
        [result appendString:@"\n-----END PUBLIC KEY-----"];
    }
    return result;
 
}
@end

 调用事例

导入#import "HBRSAHandler.h"

@implementation ViewController
{
    HBRSAHandler* _handler;
    
}
NSString* private_key_string = @"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOn0Mx9WBXbQYr55JsLKHdai1kO/iyA89YqUY3K0PK/YcCqsDNJ8y1VZQ4MBA4er6yr1LR3kSe6z6uux4oP2N4FHuV/BKM/MEkb0oyEKnuOXspOumOZ3Hn/CzpYSZSIAr5BgfADEUU9yfr+nTNIxW5sXh4bZmy3lRsSAKqeinmA9AgMBAAECgYEAxB/va2mVkxEGdl7h25HMic5giNLeMtxnixDyfYoTBecPwPYSmbH8U0RNkFkdOHMq5gw7Ej/6qp0xZvzsw2t5AtFmuAXjt1LS64ofsnbjxgKVYdMsLIn0jFSRt/riyvZLNEpNEwpbGb2Y1M9gCPHmBPU2CMgbKWvkiYquNCIVmoECQQD1wqXLRHY475AL/2AwAIUxGYeVdccL4qsDbsoUZNfaVC5iCvfgzArIg+xX4+XtKnuyuFFrRQWCVbgrsKGSn+6ZAkEA87OfAaKuRmPwMtyd4EY5GBhiOWQinWKIV9PkwozL+wyylHAdfKnMnCzglHFm5hdB+MkHs2R70R+U9DW82Vs5RQJAf+obH0x3+DSAli4Ko5FxwdeW4W0W+BG3jybYGXtPejz8k11AHYo2Rp2bozdkUmgdUC1te1bGgksZe+wIfOevaQJAU838KyrPdYNekY8Od5aOgbu443WM9cRxkIpci46xgsauDp+zdDBMHZTNMh8BPLTYyf4PuOAgOBz9MzHbnH9jZQJBAJKvVlrN3tehLIjBjzK1gfgqzIXDMZM/XkBVz8SIbz5SbeouGKCvGcSjLqD+CCFSdr8fP1EjQ0SiEwfpCpUHBcs=";


NSString* public_key_string = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDp9DMfVgV20GK+eSbCyh3WotZDv4sgPPWKlGNytDyv2HAqrAzSfMtVWUODAQOHq+sq9S0d5Enus+rrseKD9jeBR7lfwSjPzBJG9KMhCp7jl7KTrpjmdx5/ws6WEmUiAK+QYHwAxFFPcn6/p0zSMVubF4eG2Zst5UbEgCqnop5gPQIDAQAB";

//RSA加密/签名
-(void)RSAEncryptionAndDigest{
    HBRSAHandler* handler = [HBRSAHandler new];
    [handler importKeyWithType:KeyTypePrivate andkeyString:private_key_string];
    [handler importKeyWithType:KeyTypePublic andkeyString:public_key_string];
    _handler = handler;
    
    //    加密
    NSString*str=@"RSAllyouss";
    NSData *nsdata = [str dataUsingEncoding:NSUTF8StringEncoding];
    // Get NSString from NSData object in Base64
    NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];
    NSString* enString = [handler encryptWithPublicKey:base64Encoded];
    NSLog(@"RSA加密:%@", enString);
    
    //    解密
    NSString* deString = [handler decryptWithPrivatecKey:enString];
    NSData *nsdataFromBase64String = [[NSData alloc]
                                      initWithBase64EncodedString:deString options:0];
    NSLog(@"RSA解密:%@", deString);

    // Decoded NSString from the NSData
    NSString *base64Decoded = [[NSString alloc]
                               initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];

    NSLog(@"%@",base64Decoded);
    //    MD5签名
    NSString* sigMd5 = [handler signMD5String:enString];
    NSLog(@"%@ ",sigMd5);
    //   MD5验签
    BOOL isMatchMd5 = [handler verifyMD5String:enString withSign:sigMd5];
    NSLog(@"%d ",isMatchMd5);
    
}


可能写得不够详细,弄个demo大家一目了然了。加解密demo


iOS加密:AES

阅读数 227

ios sha256加密

阅读数 213

ios加密

阅读数 157

ios常用加密

博文 来自: wtj900
没有更多推荐了,返回首页