假设我们已经配置好了Java环境和JAVA_HOME变量。
生成自签名证书
1. 服务器中生成证书 ,存到指定文件夹(这里是/Desktop/myCers)
口令为changeit
.( myTomcatAlias是自己取的别名, -alias 表示证书的别名,一个keystore文件中可以存放多个alias)
keytool -genkey -alias myTomcatAlias -keyalg RSA -keystore ~/Desktop/myCers/mykeyStore -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass changeit -storepass changeit
2. 导出证书mycerts.cer
(由客户端安装)
keytool -export -alias myTomcatAlias -keystore ~/Desktop/myCers/mykeyStore -file ~/Desktop/myCers/mycerts.cer
3. 客户端配置:为客户端的jvm导入密钥(将服务器下发的证书导入到JVM中) 因为我操作的时候提示权限不足(Permission denied),所以加了sudo
sudo keytool -import -trustcacerts -alias myTomcatAlias -keystore "$JAVA_HOME/jre/lib/security/cacerts" -file ~/Desktop/myCers/mycerts.cer -storepass changeit
tomcat配置https自签名证书
1. 配置tomcat的server.xml apache-tomcat-8.5.9/conf/server.xml
Tomcat8中给出了一个默认的Connector,我们只需要把它的注释去掉就可以了。样子就像下边的图一样。
2. 启动tomcat
cd ~/Desktop/apache-tomcat-8.5.9/bin
sh startup.sh
访问 https://localhost:8443。由于自定义的证书没给第三方认证,于是出现如下图:
将之前准备好的war包放入apache-tomcat-8.5.9/webapps
目录。重新启动tomcat服务。
https://localhost:8443/JavaHttpsService/ServiceTest
访问成功
3.iOS访问https接口
iOS使用AFNetworking发起HTTPS请求就很简单了(项目需要导入mycerts.cer
)
具体可以看这篇博客
- (IBAction)doNetwork:(id)sender {
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager setSecurityPolicy:[[self class]customSecurityPolicy]];
//NSString *http1 = @"http://localhost:8080/JavaHttpsService/ServiceTest";
NSString *http2 = @"https://localhost:8443/JavaHttpsService/ServiceTest";
[manager GET:http2 parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"success: %@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error: %@",error);
}];
}
+ (AFSecurityPolicy*)customSecurityPolicy {
// /先导入证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"mycerts" ofType:@"cer"];//证书的路径
NSLog(@"%@", cerPath);
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode: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 = [[NSSet alloc]initWithObjects:certData, nil];
return securityPolicy;
}
补充
如何配置JAVA_HOME变量
定位JAVA_HOME:/usr/libexec/java_home
列出所有版本的JAVA_HOME:/usr/libexec/java_home -V
配置JAVA_HOME
➜ ~ cat ~/.bash_profile
➜ ~ JAVA_HOME=`/usr/libexec/java_home`
➜ ~ export JAVA_HOME
➜ ~ echo $JAVA_HOME
➜ ~ source ~/.bash_profile
参考资料:
数字证书中keytool命令使用说明
iOS开发:对于AFNetworking HTTP转HTTPS请求证书问题