假设我们已经配置好了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

2017051618682fix-3.png

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

2017021596827123.png

tomcat配置https自签名证书

1. 配置tomcat的server.xml apache-tomcat-8.5.9/conf/server.xml

Tomcat8中给出了一个默认的Connector,我们只需要把它的注释去掉就可以了。样子就像下边的图一样。

201705167052fix-2.png

2. 启动tomcat

cd ~/Desktop/apache-tomcat-8.5.9/bin
sh startup.sh

访问 https://localhost:8443。由于自定义的证书没给第三方认证,于是出现如下图:

2017051622846fix-1.5.png

将之前准备好的war包放入apache-tomcat-8.5.9/webapps目录。重新启动tomcat服务。

https://localhost:8443/JavaHttpsService/ServiceTest

访问成功

2017051645739fix0.png

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

2017051677210fix1.png

列出所有版本的JAVA_HOME:/usr/libexec/java_home -V

201705167047fix3.png

配置JAVA_HOME

➜  ~ cat ~/.bash_profile
➜  ~ JAVA_HOME=`/usr/libexec/java_home`
➜  ~ export JAVA_HOME
#查看结果
➜  ~ echo $JAVA_HOME
#使修改后的.bash_profile立即生效
➜  ~ source ~/.bash_profile

参考资料: 数字证书中keytool命令使用说明 iOS开发:对于AFNetworking HTTP转HTTPS请求证书问题