適配https
說明:
蘋果聲明從2017-01-01開始,所有提交的應用必須使用更安全的https協(xié)議酒请。
因此淫半,為了適配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個包可以去官網(wǎng)下載
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的解壓目錄
執(zhí)行命令:./configure--prefix=/usr/local/apr
可能會報錯:
rm: cannot remove`libtoolT': No such file or directory
則安裝libtool。Yum install libtool或者apt-get install libtool
再重新執(zhí)行黍聂,還是會報錯:
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'
再重新執(zhí)行躺苦,通過。
編譯:make
安裝:make install
注意:執(zhí)行./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機構(gòu)申請簽名證書捕捂,在申請簽名證書之前依然是創(chuàng)建自己的CSR文件
openssl req-new -key server.key -out server.csr
#向自己的CA機構(gòu)申請證書瑟枫,簽名過程需要CA的證書和私鑰參與,最終頒發(fā)一個帶有CA簽名的證書
openssl x509-req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
第四步指攒,生成cer文件
使用openssl進行轉(zhuǎn)換,客戶端使用
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
執(zhí)行./apachectl –t
如果出現(xiàn)Syntax OK
則表示配置ok。啟動httpd ./apachectl start
在瀏覽器中輸入https://服務器ip允悦,即可訪問了膝擂。到此,服務器的https服務已開通.
Webservice配置:
1.修改httpd.conf
找到這段,改為:
Options IndexesFollowSymLinks
AllowOverride None
到tomcat的目錄下架馋,修改server.xml
在這個節(jié)點下狞山,將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的數(shù)據(jù)服務器端口。并將86端口的重定向端口8443改為8086叉寂∑计簦總之,把跳轉(zhuǎn)到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轉(zhuǎn)換成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
//如果是需要驗證自建證書来庭,需要設(shè)置為YES
securityPolicy.allowInvalidCertificates=YES;
//validatesDomainName是否需要驗證域名,默認為YES穿挨;
//假如證書的域名與你請求的域名不一致月弛,需把該項設(shè)置為NO;如設(shè)成NO的話科盛,即服務器使用其他可信任機構(gòu)頒發(fā)的證書帽衙,也可以建立連接,這個非常危險贞绵,建議打開厉萝。
//置為NO,主要用于這種情況:客戶端請求的是子域名榨崩,而證書上的是另外一個域名谴垫。因為SSL證書上的域名是獨立的,假如證書上注冊的域名是www.google.com母蛛,那么mail.google.com是無法驗證通過的翩剪;當然,有錢可以注冊通配符的域名*.google.com彩郊,但這個還是比較貴的前弯。
//如置為NO舞肆,建議自己添加對應域名的校驗邏輯。
securityPolicy.validatesDomainName=NO;
securityPolicy.pinnedCertificates=[[NSSetalloc]initWithObjects:certData,nil];
returnsecurityPolicy;
}
將AFHTTPSessionManager變量的securityPolicy設(shè)置為上面方法返回的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//通過調(diào)用block,來告訴NSURLSession要不要收到這個證書
{
//(NSURLSessionAuthChallengeDisposition,
NSURLCredential * _Nullable))completionHandler
//NSURLSessionAuthChallengeDisposition(枚舉)如何處理這個證書
//NSURLCredential授權(quán)
//證書分為好幾種:服務器信任的證書前方、輸入密碼的證書狈醉。。惠险,所以這里最好判斷
if([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]){//服務器信任證書
NSURLCredential*credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];//服務器信任證書
if(completionHandler)
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
NSLog(@"....completionHandler---:%@",challenge.protectionSpace.authenticationMethod);
}