我应该如何在服务器上存储 SSL 密钥?

信息安全 tls 网络服务器
2021-08-22 14:51:51

我有一个 Node.JS HTTPS 网络服务器实例化如下:

var privateKey = fs.readFileSync('./../ssl/localhost.key').toString();
var certificate = fs.readFileSync('./../ssl/localhost.crt').toString();

https.createServer({
    key: privateKey,
    cert: certificate
}, server).listen(80, 'localhost');

我的私钥在我的服务器上,Node.JS 读取它以创建 HTTPS 网络服务器。如果黑客拥有对服务器文件的读取权限,他可以访问私钥并冒充网络服务器。

私钥是否应该存储在服务器上?一旦 HTTPS 服务器被实例化,它是否应该被销毁?

2个回答

您不想破坏您的私钥:如果您的服务器重新启动,您将再次需要它。有时会发生重启...

这是一个普遍的观察:您希望您的服务器能够以无人值守的方式重新启动。因此它必须包含私钥,并且该私钥必须对服务器软件可用。

如果攻击者劫持了您的整台机器,那么他将获得您的密钥副本。这是生活中的事实。忍受它。不过,有一些缓解措施:

  • 您可以使用 SSL 的“DHE”密码套件。使用这些密码套件,服务器密钥用于签名,而不是用于加密。这意味着窃取您的密钥的攻击者随后可以冒充您的服务器(即运行假服务器),但无法解密他之前记录的 SSL 会话。这是一个被称为Perfect Forward Secrecy的好属性。

  • 如果您将密钥存储在硬件安全模块中,则密钥不会被盗。攻击者只要能有效控制服务器,就可以玩弄密钥,但不能提取它。这降低了他的滋扰能力(但 HSM 很昂贵)。

在实践中,您只需确保包含私钥的文件仅对运行服务器的系统帐户可读(在chownchmodUnix 系统上,Windows 上的 NTFS 访问权限)。

可能您正在寻找像 nginx 这样的反向代理。它被认为是最佳实践™。

在生产环境中运行的应用程序通常需要在端口 80 (HTTP)、端口 443 (HTTPS) 或两者上运行。如果您的应用程序的多个组件与用户交互,或者您正在使用端口 80 上的 Web 服务器来交付其他资产,这可能是一个挑战。这就需要代理到 Socket.IO 服务器,而 NGINX 是最好的方法。-使用 NGINX 和 NGINX Plus 与 Node.js 和 Socket.IO,WebSocket API - nginx 博客

为生产强化 Node.JS 第 3 部分:使用 NGINX 进行零停机部署

基本上,当您尝试安全地存储私钥时,您很可能也在为负载平衡、请求限制等寻找稳定的解决方案。