https代理服务器(一)问题引出
中,始终困惑于chrome(mac)不信任我们的自签名证书
然而charles是做到了,我们从头来过,先不搞代理服务器的,先搞个简单服务器,排除是否是mac chrome就是无法信任自签名证书的谣言
1
https://www.jianshu.com/p/7cb5c2cffaaa
http://www.manongjc.com/detail/54-fqaijnnojboynez.html
跟着走
输出myhost.com.pem 和myhost.com-key.pem
python服务器启动
brew install mkcert
mkcert -install
sudo vi /etc/hosts
mkcert myhost.com
import BaseHTTPServer, SimpleHTTPServer
import ssl
httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', 443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='./myhost.com.pem', keyfile='./myhost.com-key.pem', server_side=True, ssl_version=ssl.PROTOCOL_TLSv1_2)
httpd.serve_forever()
访问https://myhost.com
safari and chrome都信任了
至此,证明了mac chrome可以信任自签名证书
2 再进一步
https://www.jianshu.com/p/7e5566f002bd
openssl pkcs12 -export -in myhost.com.pem -inkey myhost.com-key.pem -out myhost.com.p12
Enter Export Password:
Verifying - Enter Export Password:
mac@macdeMacBook Downloads %
keytool -importkeystore -deststorepass 'hhh123' -destkeypass 'hhh123' -destkeystore proxy.jks -srckeystore proxy.p12 -srcstoretype PKCS12 -srcstorepass 'hhh123' (不必须)
代理服务器失败,看来还有没有注意到的点
看了第3点的文章,认为我们制作的CA根只是签发了myhost.com的证书,而被代理的网站千千万,需要一一签发,可以先手动签发个baidu的试试
3 https://segmentfault.com/a/1190000011811150?sort=votes
自己制作的证书并不是浏览器中CA根证书签发的,所以我们需要把自己制作的CA根证书加入浏览器受信任的根证书颁发机构。
代理服务器返回的ssl证书中是由刚刚的CA证书签发的,这样就形成了一个受信任链,
java动态签发ssl证书
JAVA自带的SSL以及X509库只能使用SSL证书,不能生成SSL证书。因此我们使用“Bouncy Castle”这个算法库来实现SSL证书的生成。
//maven
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.49</version>
</dependency>
//注册bouncycastle
Security.addProvider(new BouncyCastleProvider());
//生成ssl证书公钥和私钥
KeyPairGenerator caKeyPairGen = KeyPairGenerator.getInstance("RSA", "BC");
caKeyPairGen.initialize(2048, new SecureRandom());
PrivateKey serverPriKey = keyPair.getPrivate();
PublicKey serverPubKey = keyPair.getPublic();
//通过CA私钥动态签发ssl证书
public static X509Certificate genCert(String issuer, PublicKey serverPubKey, PrivateKey caPriKey, String host) throws Exception {
X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
String issuer = "C=CN, ST=GD, L=SZ, O=lee, OU=study, CN=ProxyeeRoot";
String subject = "C=CN, ST=GD, L=SZ, O=lee, OU=study, CN=" + host;
v3CertGen.reset();
v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
v3CertGen.setIssuerDN(new X509Principal(issuer));
v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 10 * ONE_DAY));
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 3650 * ONE_DAY));
v3CertGen.setSubjectDN(new X509Principal(subject));
v3CertGen.setPublicKey(serverPubKey);
//SHA256 Chrome需要此哈希算法否则会出现不安全提示
v3CertGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
//SAN扩展 Chrome需要此扩展否则会出现不安全提示
GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.dNSName, host));
v3CertGen.addExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);
X509Certificate cert = v3CertGen.generateX509Certificate(caPriKey);
return cert;
}
至此我们最重要的功能已经实现了,接着就是拿着ssl证书返回给客户端即可捕获明文了。
4 接下去要做一些实践
python | spring boot | proxy | |||
non ca | openssl, keytool | 无需,proxy动态签发证书,必须有CA根证书顶在前面 | |||
ca | mkcert | 通过 | mac显示ca,与charles证书一样 | ||
mkcert改host | / | / | 确定二级证书是否跟域名有关 | ||
KeyStore explorer | 看看是否mac显示ca | ||||
openssl | 看看是否mac显示ca |