问题描述
”XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成”错误,chrome、firefox和Safari等ssl和非ssl没有问题,但是IE在使用ssl时会出现以上错误(前置条件使用cros方式解决ajax跨域问题)
使用openssl制作myrootca证书准备及环境mycompany
- win10 64
- 下载[http://slproweb.com/products/Win32OpenSSL.html][opensslwin64],版本Win64 OpenSSL v1.1.0h Light
- 按照默认选项进行安装到window中
制作私有到CA受信任证书
- 默认安装到地址window主机中,配置环境变量C:\OpenSSL-Win64\bin\至path
- 准备生成OpenSSL文件夹,以生成根证书及服务器证书
- 新建文件夹E:\sslca
- 将C:\OpenSSL-Win64\bin\openssl.cfg放到E:\sslca中
-
修改openssl.cfg配置文件,配置CA证书生成内容及版本等信息
- 将eq_extensions = v3_req的#取消
req_extensions = v3_req # The extensions to add to a certificate request
- 在[ v3_req ]加入subjectAltName = @alt_names
[ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] DNS.1 = mycompany.com DNS.2 = *.mycompany.com
- 加入[ alt_names ]值,为谁签发证书,注意括号前后的空格,DNS.x 的数量可以自己加, 这里的DNS就是你网站的地址,效果如下
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = mycompany.com
DNS.2 = *.mycompany.com
-
修改证书默认路径,原来
dir = ./demoCA
,修改为如下[ CA_default ] dir = ./rootCA # Where everything is kept 和 [ tsa_config1 ] # These are used by the TSA reply generation only. dir = ./rootCA # TSA root directory
-
在E:\sslca生成必要的文件夹,以便生成CA跟证书,(这些文件和文件夹是 openssl.cfg 要求的)
- 进入E:\sslca
- 执行以下命令
> mkdir rootCA\private rootCA\newcerts > type nul > rootCA\index.txt > echo 01 > rootCA\serial
生成CA自签名跟证书,用户导入系统,负责系统信任(如CA证书提前导入相同)
- 生产RootCA证书,进入进入E:\sslca执行
> openssl req -new -x509 -newkey rsa:2048 -days 3650 -keyout rootCA\private\MyRootCA.key -out rootCA\MyRootCA.crt -passout pass:123456 -config openssl.cfg
命令说明:
参数 | 描述
---------------------| ---------------------
-days 3650 | 根证书的有效期是 10年
-passout pass:123456 | CA的密钥是 123456
-config openssl.cfg | 使用当前文件夹的openssl.cfg作为默认设置, 如果不使用这个命令的话, 将使用C:\OpenSSL-Win64\bin \openssl.cfg
控制台输出:
Generating a 2048 bit RSA private key
..............................................+++
.......................+++
writing new private key to 'rootCA\private\MyRootCA.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:BeiJing
Locality Name (eg, city) []:BeiJing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:mycompanya
Organizational Unit Name (eg, section) []:mycompany.com
Common Name (e.g. server FQDN or YOUR name) []:MyRootCA
Email Address []:
- 生产用户证书
- 生产用户RSA秘钥对
>openssl genrsa -des3 -out mycompany.com.key -passout pass:123456
控制台输出:
Generating RSA private key, 2048 bit long modulus
.............+++
.............................................+++
e is 65537 (0x010001)
- 根据秘钥对生成用户证书
>openssl req -new -days 3650 -key mycompany.com.key -out mycompany.com.csr -config openssl.cfg
控制台输出,输入密码时看不到输入,其实已经输入,另外下面中的Country Name、Some-State、company必须与MyRootCA一致, 原因:
openssl.cfg中有这样一段, 当然你可以按需修改
```
[ policy_match ]
countryName = match #证书请求与证书本身一样
stateOrProvinceName = match #证书请求与证书本身一样
organizationName = match #证书请求与证书本身一样
organizationalUnitName = optional #可选项
commonName = supplied #证书请求中必须能存在该项
emailAddress = optional #可选项
```
控制台输出 :
Enter pass phrase for mycompany.com.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:BeiJing
Locality Name (eg, city) []:BeiJing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:mycompanya
Organizational Unit Name (eg, section) []:mycompany.com
Common Name (e.g. server FQDN or YOUR name) []:mycompany.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
-
使用CA证书签发用户证书,如果此处的用户证书和rootCA证书CN等信息不匹配,则无法生成证书
>openssl ca -in mycompany.com.csr -out mycompany.com.crt -cert rootCA\MyRootCA.crt -keyfile rootCA\private\MyRootCA.key -extensions v3_req -config openssl.cfg
控制台输出:
```
Using configuration from openssl.cfg
Enter pass phrase for rootCA\private\MyRootCA.key:
Can't open ./rootCA/index.txt.attr for reading, No such file or directory
14380:error:02001002:system library:fopen:No such file or directory:crypto\bio\bss_file.c:74:fopen('./rootCA/index.txt.attr','r')
14380:error:2006D080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:81:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: May 17 03:13:48 2018 GMT
Not After : May 17 03:13:48 2019 GMT
Subject:
countryName = CN
stateOrProvinceName = BeiJing
organizationName = mycompanya
organizationalUnitName = mycompany.com
commonName = mycompany.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:mycompany.com, DNS:*.mycompany.com, DNS:*.uuu.mycompany.com, DNS:*.sss.mycompany.com, DNS:auth.uuu.mycompany.com
Certificate is to be certified until May 17 03:13:48 2019 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
```
注意:如果出现./rootCA/newcerts is not a directory
需要修改openssl.cfg文件,将rootCA修改为自定义的rootCA目录,前边有讲述如何设置
-
生产p12证书,用于web服务器设置
>openssl pkcs12 -export -inkey mycompany.com.key -in mycompany.com.crt -out mycompany.com.p12
控制台输出:
```
Enter pass phrase for mycompany.com.key:
Enter Export Password:
Verifying - Enter Export Password:
```
证书必要说明
-
为什么用户证书的CN、SiChuan、YourCompany必须与MyRootCA一致?
openssl.cfg中有这样一段, 当然你可以按需修改
[ policy_match ] countryName = match #证书请求与证书本身一样 stateOrProvinceName = match #证书请求与证书本身一样 organizationName = match #证书请求与证书本身一样 organizationalUnitName = optional #可选项 commonName = supplied #证书请求中必须能存在该项 emailAddress = optional #可选项
证书验证
将RootCA证书安装到受信任的根证书颁发机构,首先安装RootCA证书,否则用户证书是不被信任的跟证书(安装到本地受信任的根证书颁发机构,安装过程请自行查找)
在Tomcat8.5中的server.xml中加入证书配置
-
配置内容如下:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="E:/ssl/mycompany.com.p12" type="RSA" certificateKeystoreType="PKCS12" certificateKeystorePassword="123456"/> </SSLHostConfig> </Connector>
浏览器访问时,证书是属于受信任的证书,不会在弹出安全提示
-
服务端代码
@ResponseBody @RequestMapping("/getinfo") public String getinfo(HttpServletRequest request,HttpServletResponse response){ Map<String,String> map = new HashMap<String,String>(); map.put("result", "hh"); Cookie[] cookies = request.getCookies(); if(null != cookies){ for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; System.out.println(cookie.getDomain() + " "+ cookie.getName()+ " "+ cookie.getPath()+ " "+ cookie.getValue() ); } } response.addHeader("Set-Cookie", "id="+request.getSession().getId()+"; Domain=.mycompany.com; Path=/"); response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin")); response.setHeader("Access-Control-Allow-Methods", "POST, GET"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); return "hello"; }
-
请求端代码
jQuery.support.cors = true//加入jQuery.support.cors = true和crossDomain:true,成对加,火狐和google不可以 $('#CORS').click(function (){ $.ajax({ url: "https://common.mycompany.com:8443/app1/getinfo", crossDomain:true, xhrFields: {//加上此处,火狐、chrome、ie7-11都可以,不需要crossDomain:true,和jQuery.support.cors = true withCredentials: true }, success: function(html){ console.log(html); console.log(document.cookie); } }); })
浏览器验证
-
IE浏览器
默认仿真器为IE7,测试时会弹出alert警告框,IE8、9仿真器可通过,IE10、11出现错误:
SEC7120: 在 Access-Control-Allow-Origin 标头中未找到源 https://java.mycompany.com:8444。
SCRIPT7002: XMLHttpRequest: 网络错误 0x80700013, 由于出现错误 80700013 而导致此项操作无法完成。
XMLHttpRequest: Network Error 0x80700013, Could not complete the operation due to error 80700013.
解决方法:Internet选项-安全,添加受信任站点(使用ajax的网站,而非ajax调用的网站,当然都加上也可以),同时将受信任站点安全级别调整到最低,IE7、8、9、10、11的问题都可以解决
-
火狐浏览器
在window安装完证书后IE可以成功,但是火狐还是会出现https安全提示,请求ajax连接时出现以下错误:
common.mycompany.com:8443 使用了无效的安全证书。该证书因为其颁发者证书未知而不被信任。该服务器可能未发送相应的中间证书。可能需要导入额外的根证书。错误代码: SEC_ERROR_UNKNOWN_ISSUER
解决方法:进入火狐浏览器的设置界面,选择 高级→证书→查看证书→证书机构→导入,将RootCA证书导入到火狐中即可(火狐和ie等不是使用同一套CA认证证书,在火狐浏览器中单独管理)
-
chrome浏览器
chrome浏览器没有问题
-
safari浏览器
safari浏览器没有问题,在mac系统中需要将RootCA证书安装到系统中,并且进行信任证书(双击证书-证书-点击对应证书-信任)。
可解决的问题
1.ajax调用时提示错误,原因实际上发现IE根本就没把请求发送出去, 所以可以说是IE截断了请求, 具体原因应该是和证书有关系, 因为CA颁发的证书就不存在该问题
SCRIPT7002: XMLHttpRequest: network error 0x2ef3
XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成