在SSL/TLS 中,客户端使用服务器的公钥。由于通常客户端事先不知道服务器的公钥,它希望通过公钥基础设施的魔力获得它:服务器的公钥将在证书中提供,客户端将能够验证:
- 证书内容是真实的(即验证:签名和名称以及证书扩展名是正确的并链接到受信任的根);
- 证书归预期的服务器所有(预期的服务器名称出现在
Subject Alt Name
证书的扩展名中,如果没有 SAN 扩展名,则出现在其公用名中)。
现在,如果客户端已经知道公钥,那么所有这些都是不必要的复杂化;如果该密钥是先验已知的,则客户端可以直接使用它而忽略服务器发送的证书。
为了与协议的正式规范兼容,并且为了更容易地重用现有的库和实现,按照您的建议进行操作可能会更简单,即验证服务器的证书是位到位的预期证书,并让代码从中提取公钥。如果“指纹”是用抗第二原像(例如 SHA-1)的散列函数计算的,则可以用于该检查。这可以。
就您而言,我了解服务器是设备,客户端是您的应用程序。只要攻击者没有破坏设备的私钥,即从设备中提取它,您的应用程序就不会被愚弄(与假设备对话)。如果您有多个设备,那么每个设备都应该有自己的私钥/公钥对。如果所有设备都具有相同的密钥对,那么私钥就不能被认为是“私人的”:超过两三个人知道的秘密不是秘密,而是谣言。
然后,“安全”的方法是在受控条件下进行某种初始化阶段,在该阶段,应用程序实例学习其随后将连接到的设备的指纹(也许应用程序生成公钥/私钥对和自签名证书,并将其导入设备)。
这是SSH中使用的安全模型:从客户端到给定服务器的第一个连接需要明确的确认(客户端显示服务器的公钥指纹,并且人类用户应该通过例如打电话给服务器来验证它系统管理员);之后,客户端信任该公钥,因为它记住了指纹。
“记住密钥”模型运行良好,但您必须意识到它丧失了被称为撤销的 PKI 功能:一种用于传送损坏遏制信息的带外自动机制。如果其中一个设备的私钥被泄露,那么窃贼随后可以运行假设备并欺骗您的应用程序连接到它;为了避免这种情况持续存在,必须以某种方式警告应用程序必须不再接受给定的证书指纹。具有定期发布的 CRL 或 OCSP 响应的吊销检查是一种自动执行此操作的方法。当您记住指纹时,没有 PKI,因此没有 CRL。但需求可能仍然存在。
如果您遵循没有 PKI 的道路,并且嵌入了证书指纹,那么您必须决定是否需要一些东西来确保 CRL 正常完成工作。