最近在研究RSA加密算法和加签算法,学习了好多相关的知识,
首先了解一下几个相关概念,以方便后面遇到的问题的解决:
RSA算法:1977年由Ron Rivest、Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字。算法基于一个数论:将两个大素数相乘非常容易,但要对这个乘积的结果进行因式分解却非常困难,因此可以把乘积公开作为公钥。该算法能够抵抗目前已知的所有密码攻击。RSA算法是一种非对称算法,算法需要一对密钥,使用其中一个加密,需要使用另外一个才能解密。我们在进行RSA加密通讯时,就把公钥放在客户端,私钥留在服务器。
PEM:既然使用RSA需要一对密钥,那么我们当然是要先使用工具来生成这样一对密钥了。在linux、unix下,最简单方便的就是使用openssl命令行了。而DER、PEM就是生成的密钥可选择的两种文件格式。DER是Distinguished Encoding Rules的简称,是一种信息传输语法规则,在ITU X.690中定义的。在ios端,我们的公钥就是需要这样一种格式的,我们可以从Certificate, Key, and Trust Services Reference这篇文档的SecCertificateCreateWithData函数的data参数的说明中看到。而PEM格式是一种对DER进行封装的格式,他只是把der的内容进行了base64编码并加上了头尾说明。openssl命令行默认输出的都是PEM格式的文件,要能够在ios下使用,我们需要指定使用DER或者先生成PEM然后转换称DER。还有那些keystore,pkcs,p7b,p12后面介绍
IOS客户端的加解密
首先我们需要导入Security.framework,
在ios中,我们主要关注四个函数
-
- SecKeyEncrypt:使用公钥对数据进行加密
- SecKeyDecrypt:使用私钥对数据进行解密
- SecKeyRawVerify:使用公钥对数字签名和数据进行验证,以确认该数据的来源合法性。什么是数字签名,可以参考百度百科这篇文章?
- SecKeyRawSign:使用私钥对数据进行摘要并生成数字签名
RSA算法有2个作用一个是加密一个是加签。从这几个函数中,我们可以看到,我们第一种是使用公钥能在客户端:加密数据,以及服务器端用私钥解密。
第二个就是用私钥在客户端加签,然后用公钥在服务器端用公钥验签。第一种完全是为了加密,第二种是为了放抵赖,就是为了防止别人模拟我们的客户端来攻击我们的服务器,导致瘫痪。
下面直接看代码吧:
- -(SecKeyRef)getPublicKey{
- NSString *certPath = [[NSBundle mainBundle] pathForResource:@"keystore" ofType:@"p7b"];
- SecCertificateRef myCertificate = nil;
- NSData *certificateData = [[NSData alloc] initWithContentsOfFile:certPath];
- myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData);
- SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
- SecTrustRef myTrust;
- OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
- SecTrustResultType trustResult;
- if (status == noErr) {
- status = SecTrustEvaluate(myTrust, &trustResult);
- }
- return SecTrustCopyPublicKey(myTrust);
- }
- -(NSString *)RSAEncrypotoTheData:(NSString *)plainText
- {
- SecKeyRef publicKey=nil;
- publicKey=[self getPublicKey];
- size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
- uint8_t *cipherBuffer = NULL;
- cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
- memset((void *)cipherBuffer, 0*0, cipherBufferSize);
- NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];
- int blockSize = cipherBufferSize-11; // 这个地方比较重要是加密问组长度
- int numBlock = (int)ceil([plainTextBytes length] / (double)blockSize);
- NSMutableData *encryptedData = [[NSMutableData alloc] init];
- for (int i=0; i<numBlock; i++) {
- int bufferSize = MIN(blockSize,[plainTextBytes length]-i*blockSize);
- NSData *buffer = [plainTextBytes subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
- OSStatus status = SecKeyEncrypt(publicKey,
- kSecPaddingPKCS1,
- (const uint8_t *)[buffer bytes],
- [buffer length],
- cipherBuffer,
- &cipherBufferSize);
- if (status == noErr)
- {
- NSData *encryptedBytes = [[[NSData alloc]
- initWithBytes:(const void *)cipherBuffer
- length:cipherBufferSize] autorelease];
- [encryptedData appendData:encryptedBytes];
- }
- else
- {
- return nil;
- }
- }
- if (cipherBuffer)
- {
- free(cipherBuffer);
- }
- NSString *encrypotoResult=[NSString stringWithFormat:@"%@",[encryptedData base64EncodedString]];
- return encrypotoResult;
- }
#import <Security/Security.h>
#import "NSData+Base64.h"
-
有问题就联系我吧!哈哈!
请看http://blog.csdn.net/jinglijun/article/details/7791032
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。
MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。
MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。
MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的, 用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不“知道”用户的密码是什么。
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
@interface MD5Hash : NSObject {
}
+ (NSString*)md5:(NSString*)str;
@end
#import "MD5Hash.h"
@implementation MD5Hash
+ (NSString*)md5:(NSString*)str {
const char*cStr =[str UTF8String];
unsigned char result[16];
CC_MD5(cStr, strlen(cStr), result);
return [NSString stringWithFormat: @"XXXXXXXXXXXXXXXX",
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]];
}
@end
// MD5字符串加密使用示例
NSString *myMD5String = [MD5Hash md5:@"123456"];
NSLog(@"MD5String: %@", myMD5String);