simon
1
一个小的、可能更大的问题:
有一个必需的 nonce 参数未在文档中提及:
def require_params
%i[public_key nonce scopes client_id application_name].each { |p| params.require(p) }
end
现在更棘手的问题。Discourse 调用 public_encrypt 方法时没有参数:
这意味着 padding 参数默认为 PKCS1_PADDING。根据 Ruby 文档:
使用公钥加密 string。padding 默认为 PKCS1_PADDING,它已知不安全,但为了向后兼容而保留。
不幸的是,Node v20.14.0(当前的 LTS 版本)在尝试使用 RSA_PKCS1_PADDING 调用 crypto.privateDecrypt 时会返回错误:
function decryptData(data: string, privateKey: string) {
const buffer = Buffer.from(data, "base64");
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING,
},
buffer
);
return decrypted.toString("utf8");
}
TypeError: RSA_PKCS1_PADDING 不再支持私有解密,这可以通过 --security-revert=CVE-2023-46809 恢复
Node 应用的一个可能修复方法是使用不安全的标志运行 Node:
node --security-revert=CVE-2023-46809
在 Discourse 端修复会很容易,但我怀疑这会破坏许多现有的集成:
public_key = OpenSSL::PKey::RSA.new(params[:public_key])
@payload = Base64.encode64(public_key.public_encrypt(@payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING))
3 个赞
@simon 是的,这绝对是 Node v22 出现问题的原因。最好不要回滚安全补丁。最好在 API 调用或 Discourse 的站点设置中设置一个标志来选择所需的填充。 (这样人们就可以保留现有的默认设置,如果他们愿意的话。)
1 个赞
大致按照这里的步骤操作,使用 NodeRSA 可以成功
sam
(Sam Saffron)
5
我明白 OAEP 被推荐用于需要抵抗 CCA / Bleichenbach 攻击的新应用程序。节点迫使我们这样做有点令人遗憾,但我想这是“为了更大的利益”。
我非常担心这会成为 Discourse 管理员需要考虑的另一个开关,这简直是一场噩梦。
相反,我们需要修复 Discourse Hub 以同时支持新旧版本,让我们的 API 能够指示公钥的“版本”。
这是一个复杂的变化,会影响到相当多的系统。您提出的修复方案会带来问题,因为一旦管理员切换到该模式,Discourse Hub 将无法工作。
3 个赞
感谢提供更多背景信息。
明确来说,这在本地开发时我会遇到问题,但当连接到我们部署在AWS EC2实例的资源时,就没有这个问题了。我猜他们的Node版本可能有一些幕后定制或版本差异,导致其加密库没有这个问题。
pmusaraj
(Penar Musaraj)
8
我刚来,但那个错误似乎不正确。这不是 Node 中被移除的功能,而是某些 OpenSSL 安装的问题。根据 Node 文档:
在 crypto.privateDecrypt() 中使用 crypto.constants.RSA_PKCS1_PADDING 需要 OpenSSL 支持隐式拒绝(rsa_pkcs1_implicit_rejection)。
另请参阅 [Bug]: RSA_PKCS1_PADDING is no longer supported for private decryption · Issue #487 · bropat/eufy-security-client · GitHub
我在本地测试,这对我来说是有效的:An example of RSA Encryption implemented in Node.js · GitHub 即使我切换到为加密和解密都使用 crypto.constants.RSA_PKCS1_PADDING 作为填充。我使用的是 OpenSSL 3.4.0 和 Node 23.6.1。
使用站点设置的棘手之处在于,客户端将不知道特定实例支持哪种填充。这使得跨实例/服务的兼容性更难理解。
我认为我们应该澄清现有实现,即明确指出我们正在使用 RSA_PKCS1_PADDING,然后再考虑升级。也许我们需要为该端点引入版本控制,以便客户端可以在 said 版本之前/之后方便地使用正确的填充。
2 个赞
simon
9
作为背景,这不是我的功能请求,只是我去年六月的一个观察。
2 个赞