适配https
说明:
苹果声明从2017-01-01开始,所有提交的应用必须使用更安全的https协议。
因此,为了适配https,服务端需要配置支持https,同时也要能使旧的应用能够依旧使用http服务。客户端从新版本开始将请求改为https。
服务端:
一.需要安装的服务:
1.openssl.在终端输入openssl,如果未支持该命令,则安装openssl
2.apache一般使用webservice的服务器,apache都已安装
3.httpd。要使用https,则必须安装httpd。可以在终端查找是否有httpd-ssl.conf这个文件,如果没有,则没有安装httpd
4.tomcat使用webservice的,一般都已有。
我们的服务器上,只需要再安装httpd
httpd安装:
httpd安装需要3个包apr.tar.gzapr-util.tar.gz httpd.tar.gz
这3个包可以去官网下载
httpd的下载地址:
apr与apr-util的下载地址:
http://apr.apache.org/download.cgi
然后把这3个包放在一个目录下。我放的与tomcat同级的目录下。/opt。
然后把这3个文件进行解压缩:
tar –xvzfhttpd-2.4.23.tar.gz
tar –xvzfapr-1.5.2.tar.gz
tar –xvzfapr-util-1.5.4.tar.gz
1.配置apr。将apr安装到/usr/local/apr下
cd apr-1.5.2跳到apr的解压目录
执行命令:./configure--prefix=/usr/local/apr
可能会报错:
rm: cannot remove`libtoolT': No such file or directory
则安装libtool。Yum install libtool或者apt-get install libtool
再重新执行,还是会报错:
config.status: executing libtoolcommands
rm: cannot remove `libtoolT': No suchfile or directory
config.status: executing defaultcommands
config.status: include/apr.h isunchanged
config.status:include/arch/unix/apr_private.h is unchanged
修改configure文件
查找$RM
"$cfgfile",将这一行注释掉
查找RM='$RM',改为RM='$RM -f'
再重新执行,通过。
编译:make
安装:make install
注意:执行./configure该配置命令的时候,一定不能有XXXX.his unchanged.
如果有这类问题,表示未配置好,需要查找原因,重新配置。否则,后面配ssl的时候,启动apache的时候,会报一些.so文件无法加载的错误。
2.配置apr-util,安装在usr/local/apr-util下
./configure--with-apr=/usr/local/apr--prefix=/usr/local/apr-util
编译:make
安装:make install
3.配置httpd,安装在usr/local/httpd下
./configure--prefix=/usr/local/httpd --enable-module=so--enable-so--enable-ssl --enable-mods-shared=all--enable-cache--enable-disk-cache --enable-file-cache--enable-mem-cache --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util
编译:make
安装:make install
生成证书:
方式1:keytool
生成为期一年的证书
keytool -genkey -alias tomcat -keyalg RSA -validity365 -keystore/Users/huanghuan1/Documents/tomcat/apache-tomcat-8.0.36/conf/.keystore
会提示输入信息,按照说明输入即可。CommonName填服务器的ip地址或域名.keystore就是一个密钥文件。
从./keystore中可以导出.key和.crt ,.cer
keytool-export -alias tomcat -keystore /opt/apache-tomcat-8.0.30/conf/.keystore -file/usr/local/ssl/certs /server.cer -storepass 123456
将上述命令的server.cer幻成server.key,导出key文件
换成server.crt导出crt文件。
即总共导出3个文件,server.key,server.crt, server.cer.
server.key和server.crt用于服务端配置。server.cer用于服务端进行证书认证。
方式2:
//第一步,为服务器端和客户端准备公钥、私钥
#生成服务器端私钥
openssl genrsa-out server.key 1024
#生成服务器端公钥
openssl rsa-in server.key -pubout -out server.pem
//第二步,生成CA证书
#生成CA私钥
openssl genrsa-out ca.key 1024
# X.509Certificate Signing Request (CSR) Management.
openssl req-new -key ca.key -out ca.csr
# X.509 CertificateData Management.
openssl x509-req -in ca.csr -signkey ca.key -out ca.crt
//第三步,生成服务器端证书
#服务器端需要向CA机构申请签名证书,在申请签名证书之前依然是创建自己的CSR文件
openssl req-new -key server.key -out server.csr
#向自己的CA机构申请证书,签名过程需要CA的证书和私钥参与,最终颁发一个带有CA签名的证书
openssl x509-req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
第四步,生成cer文件
使用openssl进行转换,客户端使用
openssl x509-in server.crt -out server.cer -outform der
SSL配置:
Cd/usr/local/httpd/conf
Vi编辑httpd.conf
去掉以下3行的注释
#LoadModule socache_shmcb_modulelibexec/apache2/mod_socache_shmcb.so
#LoadModule ssl_module libexec/apache2/mod_ssl.so
#Include /private/etc/apache2/extra/httpd-ssl.conf
cd extra,编辑httpd-ssl.conf
找到
SSLCertificateFile "/usr/local/ssl/certs/server.crt"
SSLCertificateKeyFile "/usr/local/ssl/certs/server.key"
将这里的路径换成刚刚导出的server.crt和server.key的路径
配置好之后,cd/usr/local/httpd/bin
执行./apachectl –t
如果出现Syntax OK
则表示配置ok。启动httpd ./apachectl start
在浏览器中输入https://服务器ip,即可访问了。到此,服务器的https服务已开通.
Webservice配置:
1.修改httpd.conf
找到这段,改为:
Options IndexesFollowSymLinks
AllowOverride None
到tomcat的目录下,修改server.xml
在这个节点下,将8443这个端口的注释去掉
改为:
加
maxThreads="150" SSLEnabled="true"scheme="https" secure="true"
clientAuth="false" keystoreFile="/opt/apache-tomcat-8.0.30/conf/.
keystore"keystorePass="123456" sslProtocol="TLS" />
8086即为https的数据服务器端口。并将86端口的重定向端口8443改为8086。总之,把跳转到8443的改为8086
在
加
maxThreads="150" SSLEnabled="true"scheme="https" secure="true"
clientAuth="false" keystoreFile ="/opt/apache-tomcat-8.0.30/conf/.keystore"keystorePass="123456" sslProtocol="TLS" />
配置远程控制服务器的https,端口为6001
修改web.xml,下面这段配置将影响是以http的方式还是https的方式,加了下面那段,则为https的方式,否则为http的方式
allfiles
/*
CONFIDENTIAL//需要将http转换成https进行重定向,则使用这个,否则去掉这段
因为我们要http和https共存,所以应该配为:
修改web.xml,下面这段配置将影响是以http的方式还是https的方式,加了下面那段,则为https的方式,否则为http的方式
allfiles
/*
重新启动服务,则http和https都可以使用了
http 86对应https 8086
http 4001对应https 6001
客户端
iOS AFNetworking3.0
将server.cer加到项目中。修改http请求部分
-(AFSecurityPolicy*)customSecurityPolicy
{
// /先导入证书
NSString*cerPath = [[NSBundlemainBundle]pathForResource:@"server"ofType:@"cer"];//证书的路径
NSData*certData = [NSDatadataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate使用证书验证模式
AFSecurityPolicy*securityPolicy = [AFSecurityPolicypolicyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates是否允许无效证书(也就是自建的证书),默认为NO
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates=YES;
//validatesDomainName是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName=NO;
securityPolicy.pinnedCertificates=[[NSSetalloc]initWithObjects:certData,nil];
returnsecurityPolicy;
}
将AFHTTPSessionManager变量的securityPolicy设置为上面方法返回的securityPolicy
[selfsetSecurityPolicy:[selfcustomSecurityPolicy]];
自己通过NSURLRequest写的请求
-(void)
httpWithMethod:(NSString*)method params:(NSDictionary*)dic
data:(NSData*)data msgType:(MsgType)type
requestSuccess:(HttpRequestSucessBlock)successBlock
errorHandler:(HttpRequestFailedBlock)errorBlock{
NSString*url =@"";
if(type ==MT_QUERY_GW_REMOTE){
url = [HTTPHEADstringByAppendingString:msgURL[type]];
}else{
url = [DATAHTTPHEADstringByAppendingString:msgURL[type]];
}
NSURLRequest*request = [selfURLRequestWithURL:urlparams:dicmethod:method];
NSURLSession*session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]delegate:selfdelegateQueue:[[NSOperationQueuealloc]init]];
NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
if(error){
NSLog(@"error:%@",error.description);
errorBlock(error);
}else{
NSDictionary*respDict = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingMutableLeaveserror:nil];
NSLog(@"data:%@",respDict);
successBlock(respDict);
}
}];
[dataTaskresume];
}
-(NSURLRequest*)
URLRequestWithURL:(NSString*) url params:(NSDictionary*)params
method:(NSString*) method{
NSString*requestStr = [NSStringstringWithFormat:@"%@?",url];
NSArray*allKeys = [paramsallKeys];
for(NSString*keyinallKeys){
requestStr = [NSStringstringWithFormat:@"%@%@=%@&",requestStr,key,[paramsobjectForKey:key]];
}
requestStr = [requestStrsubstringToIndex:requestStr.length-1];
NSLog(@"%@",requestStr);
NSURL*requestURL = [NSURLURLWithString:requestStr];
NSMutableURLRequest*request
= [[NSMutableURLRequestalloc]initWithURL:requestURLcachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:10];
[requestsetHTTPMethod:method];
returnrequest;
}
#pragmamark -----NSURLSessionTaskDelegate-----
//NSURLAuthenticationChallenge中的protectionSpace对象存放了服务器返回的证书信息
//如何处理证书?(使用、忽略、拒绝。。)
- (void)URLSession:(NSURLSession*)session didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDisposition,NSURLCredential*_Nullable))completionHandler//通过调用block,来告诉NSURLSession要不要收到这个证书
{
//(NSURLSessionAuthChallengeDisposition,
NSURLCredential * _Nullable))completionHandler
//NSURLSessionAuthChallengeDisposition(枚举)如何处理这个证书
//NSURLCredential授权
//证书分为好几种:服务器信任的证书、输入密码的证书。。,所以这里最好判断
if([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]){//服务器信任证书
NSURLCredential*credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];//服务器信任证书
if(completionHandler)
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
NSLog(@"....completionHandler---:%@",challenge.protectionSpace.authenticationMethod);
}