Https-证书应用
一、应用(微服务)级别解决方案1、jdk生成证书使用jdk自带的keytools生成keystore-- 打开cmd命令窗口,切换路径到jdk/bin下面C:\Program Files\Java\jdk1.8.0_60\bin>.\keytool.exe -genkeypair -alias mall-alias -keypass 123456 -keyalg RSA -keysize 1
·
一、应用(微服务)级别解决方案
1、jdk生成证书
使用jdk自带的keytools生成keystore
-- 打开cmd命令窗口,切换路径到jdk/bin下面
C:\Program Files\Java\jdk1.8.0_60\bin>.\keytool.exe -genkeypair -alias mall-alias -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore E:\git_source\mall\zlb-mall-application\cer\mall-alias.keystore -storepass 123456 -ext san=dns:localhost
执行情况如下:
在目录下可以看见当前生成的证书。
2、查看证书
.\keytool.exe -list -v -keystore E:\git_source\mall\zlb-mall-application\cer\mall-alias.keystore
执行情况如下:
查看密钥详情信息:
.\keytool.exe -list -rfc -keystore E:\git_source\mall\zlb-mall-application\cer\mall-alias.keystore
执行情况如下:
3、导出证书
C:\Program Files\Java\jdk1.8.0_60\bin>.\keytool.exe -exportcert -alias mall-alias -keystore E:\git_source\mall\zlb-mall-application\cer\mall-alias.keystore -file e:\git_source\mall\zlb-mall-application\cer\my.cer
导出证书完成
查看本地路径文件
4、代码验证证书可用性
首先用代码解析证书中的公私钥
/**
* 从KeyStore中获取公钥,并经BASE64编码
*
* @param keyStorePath
* @param alias
* @param storePass
* @author 蚂蚁兄弟
*/
public static String getStrPublicKey(String keyStorePath, String alias, String storePass) throws Exception {
PublicKey key = getPublicKey(keyStorePath, alias, storePass);
String strKey = encryptBASE64(key.getEncoded());
return strKey;
}
/**
* 获取经BASE64编码后的私钥
*
* @param keyStorePath
* @param alias
* @param storePass
* @param keyPass
* @return
* @throws Exception
* @author 蚂蚁兄弟
*/
public static String getStrPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {
PrivateKey key = getPrivateKey(keyStorePath, alias, storePass, keyPass);
String strKey = encryptBASE64(key.getEncoded());
return strKey;
}
public static void main(String[] args) throws Exception {
String keyStorePath = "E:\\git_source\\mall\\zlb-mall-application\\cer\\mall-alias.keystore";
String strPublicKey = getStrPublicKey(keyStorePath, "mall-alias", "123456");
System.out.println("公钥:"+strPublicKey);
String strPrivateKey = getStrPrivateKey(keyStorePath, "mall-alias", "123456", "123456");
System.out.println("私钥:"+strPrivateKey);
//公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYHpqAxxsgmzKP7V8Lw4gRMmzQvExyuZNuqzxou8+SPWSjlU1VrYaa07Wt/l39pEpq97B/kUI1Te6Uy09+BmhxyJ6SkDslAtCJcQDa/zfvJb4xU6m+QwtBh7DhIeFequJWRJMnOxipgF10g6jd3QNJ6/UBjGwF2gUYafaJZu+lfQIDAQAB
//私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJgemoDHGyCbMo/tXwvDiBEybNC8THK5k26rPGi7z5I9ZKOVTVWthprTta3+Xf2kSmr3sH+RQjVN7pTLT34GaHHInpKQOyUC0IlxANr/N+8lvjFTqb5DC0GHsOEh4V6q4lZEkyc7GKmAXXSDqN3dA0nr9QGMbAXaBRhp9olm76V9AgMBAAECgYBBF/dtW8YT8dV1GVIuqoEzOqyttaXRAfBAzy2Oc6+jGHpUNbNeEl8jKaz4w3xc6Uye8Vapf/Mg9DQ/n7BocT2HqjgdKve71h60lw9mgSHM9Ykjbpd1Gfk9oQrLhow8eolo+dYu/98f7ho2iBXnQJ5VjOzg8957U4UDScWqGNaEAQJBAMcfxyBwjHPjQzU/fooa1G1Df1VE94AXSfm5jHPGRvbZOgeHJGsXgcGmlysVf5ycP2tE7/n89nPCGX0FdeuIKUECQQDDkcmejsKkX7idpko7azBXzrSNWzZojzEdyoXaLjLFeNkF4cGwb94fF4Lz5wckfcT8mCKB+J2tKzxtIkMAIJE9AkACSnlOBD15b9nsGOjpydk70JT8dCiszpfJSbs18cgLOwCR6ZofqUuS4MnIcxzevmV0ZHymUaS8PDVy3Mc4iH6BAkEAosbxXbvNXisd6nnCR3qMHkm6Ff3ZZ2Xnp7gteNADCkHvwOmK4WP7KT3UjVW5qDHWh7fI4Q0hkETwYpWl1rFEsQJBAJpEmUOzCqtHDQjvsXVYVT93dyhZNtNZISenJ8qFSKSDlvUmrxU6xX66tU5vX3ExSueXZ89zKCKbMm/muOCl7Iw=
}
然后用代码验证公私钥的可用性
public static void main(String[] args) throws Exception {
//生成公钥和私钥
Map<String, String> keyMap = new HashMap<>();
keyMap.put("publicKey", "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYHpqAxxsgmzKP7V8Lw4gRMmzQvExyuZNuqzxou8+SPWSjlU1VrYaa07Wt/l39pEpq97B/kUI1Te6Uy09+BmhxyJ6SkDslAtCJcQDa/zfvJb4xU6m+QwtBh7DhIeFequJWRJMnOxipgF10g6jd3QNJ6/UBjGwF2gUYafaJZu+lfQIDAQAB");
keyMap.put("privateKey", "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJgemoDHGyCbMo/tXwvDiBEybNC8THK5k26rPGi7z5I9ZKOVTVWthprTta3+Xf2kSmr3sH+RQjVN7pTLT34GaHHInpKQOyUC0IlxANr/N+8lvjFTqb5DC0GHsOEh4V6q4lZEkyc7GKmAXXSDqN3dA0nr9QGMbAXaBRhp9olm76V9AgMBAAECgYBBF/dtW8YT8dV1GVIuqoEzOqyttaXRAfBAzy2Oc6+jGHpUNbNeEl8jKaz4w3xc6Uye8Vapf/Mg9DQ/n7BocT2HqjgdKve71h60lw9mgSHM9Ykjbpd1Gfk9oQrLhow8eolo+dYu/98f7ho2iBXnQJ5VjOzg8957U4UDScWqGNaEAQJBAMcfxyBwjHPjQzU/fooa1G1Df1VE94AXSfm5jHPGRvbZOgeHJGsXgcGmlysVf5ycP2tE7/n89nPCGX0FdeuIKUECQQDDkcmejsKkX7idpko7azBXzrSNWzZojzEdyoXaLjLFeNkF4cGwb94fF4Lz5wckfcT8mCKB+J2tKzxtIkMAIJE9AkACSnlOBD15b9nsGOjpydk70JT8dCiszpfJSbs18cgLOwCR6ZofqUuS4MnIcxzevmV0ZHymUaS8PDVy3Mc4iH6BAkEAosbxXbvNXisd6nnCR3qMHkm6Ff3ZZ2Xnp7gteNADCkHvwOmK4WP7KT3UjVW5qDHWh7fI4Q0hkETwYpWl1rFEsQJBAJpEmUOzCqtHDQjvsXVYVT93dyhZNtNZISenJ8qFSKSDlvUmrxU6xX66tU5vX3ExSueXZ89zKCKbMm/muOCl7Iw=");
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
System.out.println("公钥:"+publicKey);
System.out.println("私钥:"+privateKey);
// 原始字符串
String message = "测试公钥加密私钥解密 原始内容";
System.out.println("原始数据:"+message);
String messageEn = publicKeyEncrypt(message, publicKey);
System.out.println("公钥加密后内容:" + messageEn);
String messageDe = privateKeyDecrypt(messageEn, privateKey);
System.out.println("私钥解密后内容:" + messageDe);
System.out.println("===============================");
message = "测试私钥加密公钥解密 原始内容";
System.out.println("原始数据:"+message);
String messageEn1 = privateKeyEncrypt(message, privateKey);
System.out.println("私钥加密后内容:" + messageEn1);
String messageDe1 = publicKeyDecrypt(messageEn1, publicKey);
System.out.println("公钥解密后内容:" + messageDe1);
}
/**
* RSA公钥加密
*
* @param str 加密字符串
* @param publicKey 公钥
* @return 密文
* @throws Exception 加密过程中的异常信息
* @author 蚂蚁兄弟
*/
public static String publicKeyEncrypt(String str, String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").
generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* RSA私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
* @author 蚂蚁兄弟
*/
public static String privateKeyDecrypt(String str, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
/**
* RSA私钥加密
*
* @param str
* @param privateKey
* @return
* @throws Exception
*/
public static String privateKeyEncrypt(String str, String privateKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").
generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, priKey);
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes()));
return outStr;
}
/**
* RSA公钥解密
*
* @param str
* @param publicKey
* @return
* @throws Exception
*/
public static String publicKeyDecrypt(String str, String publicKey) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(publicKey);
PublicKey pubKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
5、配置证书到springboot项目
首先将刚刚生成的证书文件放到项目resources目录下,然后在application.yml中配置如下信息。
server:
ssl:
key-store: classpath:mall-alias.keystore
key-store-type: JKS
key-alias: mall-alias
key-store-password: 123456
key-password: 123456
此时在浏览器访问:https协议时,提示如下信息。说明证书配置完成。
6、安装证书
双击my.cer安装证书。
安装完成证书后,再次访问,就不会出现“不安全”的提示了。
二、网络负载级别解决方案
1、安装openSSL,执行如下命令
PS E:\git_source\mall\zlb-mall-application\cer\nginx> openssl genrsa -des3 -out mall.key 1024
Loading 'screen' into random state - done
Generating RSA private key, 1024 bit long modulus
..................++++++
....++++++
e is 65537 (0x10001)
Enter pass phrase for mall.key:
Verifying - Enter pass phrase for mall.key:
PS E:\git_source\mall\zlb-mall-application\cer\nginx> openssl req -new -key mall.key -out mall.csr
Enter pass phrase for mall.key:
Loading 'screen' into random state - done
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]:bj
Locality Name (eg, city) []:bj
Organization Name (eg, company) [Internet Widgits Pty Ltd]:hw
Organizational Unit Name (eg, section) []:zg
Common Name (e.g. server FQDN or YOUR name) []:cpf.com
Email Address []:422121212@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
PS E:\git_source\mall\zlb-mall-application\cer\nginx> openssl rsa -in .\mall.key.src -out mall.key
Enter pass phrase for .\mall.key.src:
writing RSA key
PS E:\git_source\mall\zlb-mall-application\cer\nginx> openssl x509 -req -days 365 -in .\mall.csr -signkey .\mall.key -out mall.crt
Loading 'screen' into random state - done
Signature ok
subject=/C=cn/ST=bj/L=bj/O=msb/OU=msb/CN=cpf.com/emailAddress=asdasdf@qq.com
Getting Private key
PS E:\cer2\nginx>
2、配置nginx.conf
主要是如下两处,一般企业都是通过CA授权方购买证书,配置上证书信息即可。
ssl_certificate E://git_source//mall//zlb-mall-application//cer//nginx//dongbao.crt;
ssl_certificate_key E://git_source//mall//zlb-mall-application//cer//nginx//dongbao.key;
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
upstream com.cpf {
server 127.0.0.1:8080; # 需要监听的端口名 我用的
keepalive 64;
}
# HTTPS server
#
server {
listen 443 ssl;
server_name cpf.com;
ssl_certificate E://git_source//mall//zlb-mall-application//cer//nginx//dongbao.crt;
ssl_certificate_key E://git_source//mall//zlb-mall-application//cer//nginx//dongbao.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://com.cpf;
}
}
}
更多推荐
已为社区贡献3条内容
所有评论(0)