OpenSSL创建客户端、服务器证书,ios双向https认证

1 篇文章 0 订阅
1 篇文章 0 订阅

成功配出了各种证书的一篇好文章。

转自:http://blog.csdn.net/jerryvon/article/details/8548802?reload


一.生成证书

  • 生成CA证书。目前不使用第三方权威机构的CA来认证,自己充当CA的角色。

1.创建私钥:
openssl genrsa -out root/root-key.pem 1024 
2.创建证书请求:
openssl req -new -out root/root-req.csr -key root/root-key.pem
3.自签署证书:
openssl x509 -req -in root/root-req.csr -out root/root-cert.pem -signkey root/root-key.pem -days 3650 
4.将证书导出成浏览器支持的.p12格式:
openssl pkcs12 -export -clcerts -in root/root-cert.pem -inkey root/root-key.pem -out root/root.p12

  • 生成server证书

1.创建私钥:
openssl genrsa -out server/server-key.pem 1024 
2.创建证书请求:
openssl req -new -out server/server-req.csr -key server/server-key.pem 
3.自签署证书:
openssl x509 -req -in server/server-req.csr -out server/server-cert.pem -signkey server/server-key.pem -CA root/root-cert.pem -CAkey root/root-key.pem -CAcreateserial -days 3650 
4.将证书导出成浏览器支持的.p12格式:
openssl pkcs12 -export -clcerts -in server/server-cert.pem -inkey server/server-key.pem -out server/server.p12

  • 生成client证书

1.创建私钥:
openssl genrsa -out client/client-key.pem 1024 
2.创建证书请求:
openssl req -new -out client/client-req.csr -key client/client-key.pem 
3.自签署证书:
openssl x509 -req -in client/client-req.csr -out client/client-cert.pem -signkey client/client-key.pem -CA root/root-cert.pem -CAkey root/root-key.pem -CAcreateserial -days 3650 
4.将证书导出成浏览器支持的.p12格式:
openssl pkcs12 -export -clcerts -in client/client-cert.pem -inkey client/client-key.pem -out client/client.p12

  • 根据root证书生成jks文件
进入root目录

keytool -import -v -trustcacerts -storepass password -alias root -file root-cert.pem -keystore root.jks


Tomcat 配置

 <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
        maxThreads="150" scheme="https" schemeecure="true"
        keystoreType="PKCS12" keystoreFile="/Users/fengchao/cer/server/server.p12" keystorePass="1234"
        truststoreType="JKS" truststoreFile="/Users/fengchao/cer/root/root.jks" truststorePass="password" 
        clientAuth="false" sslProtocol="TLS" />

注意参数大小写,和路径的写法,这个是mac配置

主要参数是SSLEnable,是否启用HTTPS,如果true,则用户用浏览器访问8443时,会提示要在浏览器里添加证书,因为我们是自签名,属于非认证签名,所以会提示,如果是第三方认证则的SSL证书,则浏览器默认通过,可以直接安全访问。iOS客户端如果将认真安全跳过,则可以直接访问,如果开启则不能访问。

clientAuth是否启用客户端验证,也可以说是否是双向认证,浏览器访问时会寻找系统登陆中的keychain,如果你安装过对应的client,则会出现选择框让用户选择,选择后提交则会正常显示。iOS则也类似,需要读取本地证书,然后带证书提交。

二.iOS客户端 https单向验证

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. NSURL *url = [NSURL URLWithString:@"https://localhost:8443/deploy/index.html"];  
  2. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];  
  3. [request setValidatesSecureCertificate:YES];//set to NO if you use the self-signed certificate  
如果这个时候你开启验证,则会返回如下错误

A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)

因为我们的证书是自签名,而苹果已经明确提示,你的证书可能是自签名,所以导致失败。

则个时候如果访问其他HTTPS网站则不会报错,所以这个验证只有在正式的证书才有效果。这个也很合理,如果你的客户端自签名都能通过,这样没有安全可言。除非你让用户自己选择是否信任。


三.iOS客户端  https双向验证

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1.       
  2.      SecIdentityRef identity = NULL;  
  3.     SecTrustRef trust = NULL;  
  4. //    SecCertificateRef myReturnedCertificate = NULL;  
  5.      NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]];  
  6. //    NSLog(@"%@",[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]);  
  7.         [ASIHTTPRequestDemo extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];  
  8.        [request setClientCertificateIdentity:identity];  
  9. //    status = SecIdentityCopyCertificate (identity,&myReturnedCertificate);   
  10. //        [request setClientCertificates:[NSArray arrayWithObject:(id)PKCS12Data]];  
  11.   
  12.   
  13.     [request startSynchronous];  
  14.     NSError *error = [request error];  
  15.   
  16.   
  17.     if (!error) {  
  18.             //do something  
  19.       }  
  20. ......  
  21. }  


思路就是读取p12文件,然后将证书内容和证书密钥导出,然后将证书塞入request,随后startSynchronous

由于没有正式证书,目前没有通过。所以如果有正式证书后再验证。或者已经验证过的朋友请留言交流下,在下感激不尽。

下面是提取P12信息代码

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. + (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data  
  2. {  
  3.     OSStatus securityError = errSecSuccess;  
  4.       
  5. //  NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"" forKey:(id)kSecImportExportPassphrase];  
  6.       
  7.     CFStringRef password = CFSTR("1234"); //证书密码  
  8.     const void *keys[] =   { kSecImportExportPassphrase };  
  9.     const void *values[] = { password };  
  10.       
  11.     CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys,values, 1,NULL, NULL);  
  12.     CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);  
  13.     securityError = SecPKCS12Import((CFDataRef)inPKCS12Data,(CFDictionaryRef)optionsDictionary,&items);  
  14.       
  15.     if (securityError == 0) {  
  16.         CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);  
  17.         const void *tempIdentity = NULL;  
  18.         tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);  
  19.         *outIdentity = (SecIdentityRef)tempIdentity;  
  20.         const void *tempTrust = NULL;  
  21.         tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);  
  22.         *outTrust = (SecTrustRef)tempTrust;  
  23.     } else {  
  24.         NSLog(@"Failed with error code %d",(int)securityError);  
  25.         return NO;  
  26.     }  
  27.     return YES;  
  28. }  

四.RSA服务端加密,客户端解密
根据私钥和csr导出公钥

openssl x509 -req -in root-req.csr -out root_public_key.der -outform der -signkey root-key.pem -days 3650

如果重新来制作密钥则可以执行

openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650

这个语句等于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

客户端代码主要如下

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. NSString *pkcsPath = [[NSBundle mainBundle] pathForResource:@"root" ofType:@"p12"];  
  2. // 下面的与上面的一样  
  3.    //   NSString *pkcsPath = [[NSBundle mainBundle] pathForResource:@"pkcs-daniate" ofType:@"pfx"];  
  4. NSString *certPath = [[NSBundle mainBundle] pathForResource:@"server_public_key" ofType:@"der"];  
  5.   
  6. Security *security = [Security sharedSecurity];  
  7.   
  8. OSStatus status = -1;  
  9.   
  10. status = [security extractEveryThingFromPKCS12File:pkcsPath passphrase:@"1234"];  
  11. NSLog(@"status = %ld", status);  
  12. // 取得公钥  
  13. status = [security extractPublicKeyFromCertificateFile:certPath];  
  14. NSLog(@"status = %ld", status);  
  15. // 苹果官方文档中只说了短数据加密,但也提到了长数据的分段加密  
  16. // 短数据  
  17.     NSString *plainText = @"This is plain text~中华人民共和国~";  
  18. NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding];  
  19. NSData *encrypted = [security encryptWithPublicKey:plainData];  
  20. NSData *decrypted = [security decryptWithPrivateKey:encrypted];  
  21.  //  NSString *encryptedText = [[NSString alloc] initWithData:encrypted encoding:NSUTF8StringEncoding];  
  22. NSString *decryptedText = [[NSString alloc] initWithData:decrypted encoding:NSUTF8StringEncoding];  
  23.      
  24.    //   NSLog(@"plainData: %p", plainData);  
  25.    //   NSLog(@"encrypted: %p", encrypted);  
  26.    //   NSLog(@"decrypted: %p", decrypted);  
  27.    NSLog(@"encrypted: %@",encrypted);  
  28. NSLog(@"decrypted text: %@", decryptedText);  
p12文件包含私密,der则是包含公钥,分别提取并且利用其加密解密,从而达到验证的目的。








参考:1.http://since2006.com/blog/39/using-tomcat-ssl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值