HTTPS安全加固是提升网站安全性的重要措施,旨在防止攻击、保护用户数据并确保通信的机密性和完整性,在对安全有严格要求的相关行业,SSL/TLS的安全评估是必要的项目,本文将从多维度论述
证书管理
证书管理是HTTPS安全加固中的关键环节,涉及证书的申请、部署、更新、撤销以及监控等操作。有效的证书管理可以确保证书的合法性、有效性和安全性,从而保障HTTPS连接的安全,一个优秀的证书管理模块应具备高效、安全、可扩展和易用等特性,能够满足现代企业对证书管理的复杂需求
- 自动化证书生命周期管理:支持与证书颁发机构(CA)集成,自动完成证书的申请、签发和部署,
- 安全性:提供细粒度的权限管理,确保只有授权人员可以访问和操作证书,并记录所有证书操作
- 监控与告警:实时监控证书的有效期,提前通知续期,在证书配置错误、私钥泄露或CA服务异常时,及时发出告警
推荐的开源库:
- Cert-Manager:基于 Kubernetes 的证书管理工具,专为云原生环境设计
- HashiCorp Vault:HashiCorp推出集中化的密钥和证书管理工具,如果同样使用consul作为微服务注册中心可以考虑
服务器配置
配置服务器的 HTTPS 安全是确保数据传输加密、防止中间人攻击和保护用户隐私的关键步骤
- Nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate chain.pem;
ssl_certificate_key privkey.pem;
proxy_ssl_verify on; # 开启SSL验证
ssl_ecdh_curve X25519:P-256; # ECC椭圆曲线
ssl_protocols TLSv1.2 TLSv1.3; # 禁用旧版本
ssl_ciphers HIGH:!aNULL:!MD5; # 配置强加密套件
ssl_prefer_server_ciphers on; #选择密码套件时,以服务端为准
location / {
root /var/www/html;
index index.html;
}
}
- Apache
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
DocumentRoot /var/www/html
</VirtualHost>
强制使用 HTTPS
强制使用 HTTPS 是确保所有流量都通过加密通道传输的关键措施,可以有效防止中间人攻击、数据泄露和会话劫持
HTTP 到 HTTPS 的禁用/重定向
- nginx
#重定向https请求
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
- apache
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
启用 HSTS
- nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
- Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preloa
客户端配置
客户端配置同样是是确保客户端与服务器之间安全通信的重要环节,通过双向安全配置,可以更好的确保HTTPS的安全
- OkHttp
@Bean
@Primary
public OkHttpClient secureFeignClient(X509TrustManager trustManager) throws Exception {
// 客户端支持的数字签名算法
System.setProperty("jdk.tls.client.SignatureSchemes", "rsa_pss_rsae_sha256,rsa_pss_rsae_sha384,rsa_pkcs1_sha256");
// 客户端支持的密钥加密算法
System.setProperty("jdk.tls.namedGroups", "secp256r1,secp384r1");
OkHttpClient.Builder builder = new OkHttpClient.Builder();
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
// 客户端支持的TLS版本
.tlsVersions(TlsVersion.TLS_1_2,TlsVersion.TLS_1_3)、
// 客户端支持的套件
.cipherSuites(
CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
)
.build();
builder.setConnectionSpecs$okhttp(Lists.newArrayList(spec));
builder.retryOnConnectionFailure(true);
return builder.build();
- RestTemplate
@Bean
public RestTemplate safeRestTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
// 客户端支持的数字签名算法
System.setProperty("jdk.tls.client.SignatureSchemes", "rsa_pss_rsae_sha256,rsa_pss_rsae_sha384,rsa_pkcs1_sha256");
// 客户端支持的密钥加密算法
System.setProperty("jdk.tls.namedGroups", "secp256r1,secp384r1");
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
String[] supportedCipherSuites = {
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
};
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, supportedCipherSuites,null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(requestFactory);
return restTemplate;
}