首页 新闻 会员 周边

IOS开发中,RSA的加密需要的公钥和私钥是java后台给的么,还是自己生成!(MD5)

0
悬赏园豆:100 [已关闭问题] 关闭于 2015-04-29 20:02

    本人做银行项目,要用RSA加密用户的信息,求IOS中RSA加密的流程。

IOS开发中,RSA的加密需要的公钥和私钥是服务端后台给的么,还是自己生成!还是说ios端的公钥和私钥ios端生成,到时候把私钥给服务器后台,公钥留着自己加密。   而服务端的公钥和私钥自己生成,只需要把私钥给ios端,公钥自己留着加密?我也是喝酒了,感觉!

RSA
MJBigFans的主页 MJBigFans | 初学一级 | 园豆:7
提问于:2015-04-18 17:45
< >
分享
所有回答(1)
0

在 iOS 上, 加密被和安全性进行了强绑定, 所以, 你不能只做加密(至少公开文档不告诉你如何只做加密). 但事实上, 很多时候我们加密, 并不是要求 100% 的安全, 只是希望能得到加密本身所带来的安全, 既不考虑数据重放, 也不考虑第三者攻击, 也不考虑身份伪装. 我们仅仅是需要RSA加密。

下面介绍三种方法:

  • iOS通常的RSA加密方法--Security.framework
  • openssl库编译到iOS工程中,详见:https://github.com/x2on/OpenSSL-for-iPhone
  • IOS RSA API,这个是专用于IOS的RSA算法API,使用简单效率高效,但不是免费地。有需要可联系:QQ1561724180    手机:13803113171

===================

iOS通常的RSA加密方法--Security.framework

===================

通常,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

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

RSA.m

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 }

 

 

LiuKaiFa | 园豆:1491 (小虾三级) | 2015-04-18 19:45

请问一下我按照百度的流程做,为什么第一步openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650后:有phrase is too short, needs to be at least 4 chars的错误提示!而且用终端生成的.pem文件在哪里?在哪里看到,MAC有没有bin文件

支持(0) 反对(0) MJBigFans | 园豆:7 (初学一级) | 2015-04-19 18:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册