iOS下的RSA加密方法
2013-08-12 15:54
393 查看
最近几天折腾了一下如何在iOS上使用RSA来加密。iOS上并没有直接的RSA加密API。但是iOS提供了x509的API,而x509是支持RSA加密的。因此,我们可以通过制作自签名的x509证书(由于对安全性要求不高,我们并不需要使用CA认证的证书),再调用x509的相关API来进行加密。接下来记录一下整个流程。
第一步,制作自签名的证书
1.最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
按照命令行的提示输入内容就行了。
几个说明:
public_key.der是输出的自签名的x509证书,即我们要用的。
private_key.pem是输出的私钥,用来解密的,请妥善保管。
rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。
-days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。
事实上,这一行命令包含了好几个步骤(我研究下面这些步骤的原因是我手头已经由一个private_key.pem私钥了,想直接用这个来生成x509证书,也就是用到了下面的2-3)
1)创建私钥
openssl genrsa -out private_key.pem 1024
2)创建证书请求(按照提示输入信息)
openssl req -new -out cert.csr -key private_key.pem
3)自签署根证书
openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650
2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。如下图所示:
第二步,使用public_key.der来进行加密。
1.导入Security.framework。
2.把public_key.der放到mainBundle中(一般直接拖到Xcode就行啦)。
3.从public_key.der读取公钥。
4.加密。
下面是参考代码(只能用于加密长度小于等于116字节的内容,适合于对密码进行加密。使用了ARC,不过还是要注意部分资源需要使用CFRealse来释放)
RSA.h
RSA.m
使用方法:
参考:
1. (原创)如何生成以及导入X.509证书
http://hi.baidu.com/five00/blog/item/43bf1fd77df2d8d9a044df39.html
2. ios下使用rsa算法与php进行加解密通讯
http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/
3. Certificate, Key, and Trust Services Reference
http://developer.apple.com/library/mac/#documentation/security/Reference/certifkeytrustservices/Reference/reference.html
4. X509
http://baike.baidu.com/view/2841580.htm
5. RSA
http://zh.wikipedia.org/zh/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
第一步,制作自签名的证书
1.最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
按照命令行的提示输入内容就行了。
几个说明:
public_key.der是输出的自签名的x509证书,即我们要用的。
private_key.pem是输出的私钥,用来解密的,请妥善保管。
rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。
-days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。
事实上,这一行命令包含了好几个步骤(我研究下面这些步骤的原因是我手头已经由一个private_key.pem私钥了,想直接用这个来生成x509证书,也就是用到了下面的2-3)
1)创建私钥
openssl genrsa -out private_key.pem 1024
2)创建证书请求(按照提示输入信息)
openssl req -new -out cert.csr -key private_key.pem
3)自签署根证书
openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650
2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。如下图所示:
第二步,使用public_key.der来进行加密。
1.导入Security.framework。
2.把public_key.der放到mainBundle中(一般直接拖到Xcode就行啦)。
3.从public_key.der读取公钥。
4.加密。
下面是参考代码(只能用于加密长度小于等于116字节的内容,适合于对密码进行加密。使用了ARC,不过还是要注意部分资源需要使用CFRealse来释放)
RSA.h
01 | // |
02 | // RSA.h |
03 | // |
04 | #import <Foundation/Foundation.h> |
05 |
06 | @interface RSA : NSObject { |
07 | SecKeyRef publicKey; |
08 | SecCertificateRef certificate; |
09 | SecPolicyRef policy; |
10 | SecTrustRef trust; |
11 | size_t maxPlainLen; |
12 | } |
13 |
14 | - (NSData *) encryptWithData:(NSData *)content; |
15 | - (NSData *) encryptWithString:(NSString *)content; |
16 |
17 | @end |
01 | // |
02 | // RSA.m |
03 | // |
04 | #import "RSA.h" |
05 |
06 | @implementation RSA |
07 |
08 | - (id)init { |
09 | self = [super init]; |
10 |
11 | NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@ "public_key" |
12 | ofType:@ "der" ]; |
13 | if (publicKeyPath == nil) { |
14 | NSLog(@ "Can not find pub.der" ); |
15 | return nil; |
16 | } |
17 |
18 | NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath]; |
19 | if (publicKeyFileContent == nil) { |
20 | NSLog(@ "Can not read from pub.der" ); |
21 | return nil; |
22 | } |
23 |
24 | certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent); |
25 | if (certificate == nil) { |
26 | NSLog(@ "Can not read certificate from pub.der" ); |
27 | return nil; |
28 | } |
29 |
30 | policy = SecPolicyCreateBasicX509(); |
31 | OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust); |
32 | if (returnCode != 0) { |
33 | NSLog(@ "SecTrustCreateWithCertificates fail. Error Code: %ld" , returnCode); |
34 | return nil; |
35 | } |
36 |
37 | SecTrustResultType trustResultType; |
38 | returnCode = SecTrustEvaluate(trust, &trustResultType); |
39 | if (returnCode != 0) { |
40 | NSLog(@ "SecTrustEvaluate fail. Error Code: %ld" , returnCode); |
41 | return nil; |
42 | } |
43 |
44 | publicKey = SecTrustCopyPublicKey(trust); |
45 | if (publicKey == nil) { |
46 | NSLog(@ "SecTrustCopyPublicKey fail" ); |
47 | return nil; |
48 | } |
49 |
50 | maxPlainLen = SecKeyGetBlockSize(publicKey) - 12; |
51 | return self; |
52 | } |
53 |
54 | - (NSData *) encryptWithData:(NSData *)content { |
55 |
56 | size_t plainLen = [content length]; |
57 | if (plainLen > maxPlainLen) { |
58 | NSLog(@ "content(%ld) is too long, must < %ld" , plainLen, maxPlainLen); |
59 | return nil; |
60 | } |
61 |
62 | void *plain = malloc (plainLen); |
63 | [content getBytes:plain |
64 | length:plainLen]; |
65 |
66 | size_t cipherLen = 128; // 当前RSA的密钥长度是128字节 |
67 | void *cipher = malloc (cipherLen); |
68 |
69 | OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain, |
70 | plainLen, cipher, &cipherLen); |
71 |
72 | NSData *result = nil; |
73 | if (returnCode != 0) { |
74 | NSLog(@ "SecKeyEncrypt fail. Error Code: %ld" , returnCode); |
75 | } |
76 | else { |
77 | result = [NSData dataWithBytes:cipher |
78 | length:cipherLen]; |
79 | } |
80 |
81 | free (plain); |
82 | free (cipher); |
83 |
84 | return result; |
85 | } |
86 |
87 | - (NSData *) encryptWithString:(NSString *)content { |
88 | return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]]; |
89 | } |
90 |
91 | - ( void )dealloc{ |
92 | CFRelease(certificate); |
93 | CFRelease(trust); |
94 | CFRelease(policy); |
95 | CFRelease(publicKey); |
96 | } |
97 |
98 | @end |
1 | RSA *rsa = [[RSA alloc] init]; |
2 | if (rsa != nil) { |
3 | NSLog(@ "%@" ,[rsa encryptWithString:@ "test" ]); |
4 | } |
5 | else { |
6 | NSLog(@ "init rsa error" ); |
7 | } |
1. (原创)如何生成以及导入X.509证书
http://hi.baidu.com/five00/blog/item/43bf1fd77df2d8d9a044df39.html
2. ios下使用rsa算法与php进行加解密通讯
http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/
3. Certificate, Key, and Trust Services Reference
http://developer.apple.com/library/mac/#documentation/security/Reference/certifkeytrustservices/Reference/reference.html
4. X509
http://baike.baidu.com/view/2841580.htm
5. RSA
http://zh.wikipedia.org/zh/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
相关文章推荐
- iOS下的RSA加密方法
- iOS下的RSA加密方法
- iOS——RSA加密方法
- iOS下的RSA加密方法
- iOS下的RSA加密方法
- iOS下的RSA加密方法
- iOS下的RSA加密方法
- 关于IOS 中RSA加密的方法
- iOS下的RSA加密方法
- ios常见加密解密方法(RSA、DES 、AES、MD5)
- iOS常用加密方法(aes、md5、base64)
- ios php RSA 非对称加密解密 der 和pem生成
- android、ios与服务器端php使用rsa加密解密通讯
- PHP的RSA加密解密方法以及开发接口使用
- iOS安全之RSA加密/生成公钥、秘钥 pem文件
- Cryptopp iOS 使用 RSA加密解密和签名验证签名
- IOS 使用AF网络请求统一RSA加密+URL不识别中文的解决办法
- ios中AES和RSA 加密
- iOS RSA加密 以及生成公钥 秘钥 pem文件
- iOS 客户端进行 RSA 加密并在 PHP 服务端进行解密