Google KSM does not sign RSA PKCS v1.5 through OpenSSL / PKCS#11 with "mechanism 0xd is not permitted for key"

huangapple go评论71阅读模式
英文:

Google KSM does not sign RSA PKCS v1.5 through OpenSSL / PKCS#11 with "mechanism 0xd is not permitted for key"

问题

我们正在尝试使用存储在HSM中生成的私钥来建立mTLS连接。我们正在使用Google KMS来管理HSM部分。

我们的应用程序是一个Node.js应用,使用axios来发起请求,并且我们配置了底层的openssl / pkcs#11接口如下:

httpsAgent = new Agent({
  privateKeyEngine: 'pkcs11',
  privateKeyIdentifier,
  cert: fullCert
})

在我们的开发环境中,这个设置正常工作,我们使用了LetsEncrypt证书,使用2048位RSA密钥,并使用RSA-PSS作为签名算法。我们将从certbot获取的密钥导入到HSM中,选择了rsa-sign-pss-2048-sha256作为签名算法,密钥用途为ASYMMETRIC_SIGNING。

然而,在生产环境中,我们被要求使用特定CA的证书。我们直接在HSM中生成了生产密钥(因此无法提取私钥),使用OpenSSL生成CSR供CA使用,但注意到他们不接受使用RSA-PSS的CSR。

因此,我们不得不降级签名算法为PKCS v1.5,以便CA接受CSR。

CA接受了CSR,签署了证书,我们将一切设置得与开发环境相同。但是,当我们尝试建立连接时,我们现在收到以下错误:

module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:116

此外,Google的KMS集成记录了以下信息:

returning 0x68 from C_SignInit due to status FAILED_PRECONDITION: at preconditions.cc:47: mechanism 0xd is not permitted for key
returning 0x70 from C_SignInit due to status INVALID_ARGUMENT: at crypter_ops.cc:62: mechanism 0x3 is not valid for operation sign

现在,我不是密码学专家,但我理解的方式是:

  • 如果我在Google KMS中使用"2048位RSA密钥PKCS#1 v1.5填充 - SHA256摘要"作为密钥算法,然后成功使用OpenSSL生成CSR,那么与使用"2048位RSA密钥PSS填充 - SHA256摘要"相比,这不应该是相同的吗?

我们使用的是Node v16,Debian 11.6,带有OpenSSL 1.1.1n。我尝试升级了PKCS#11引擎至最新版本,但没有效果。

是否需要设置任何标志或配置,以便Node/OpenSSL知道要使用哪种机制?OpenSSL报告引擎支持RSA_PKCS。

英文:

We are trying to setup a mTLS connection using a private key that is generated and stored in a HSM. We are using Google KMS for the HSM part.

Our application is a Nodejs app that uses axios to make requests, and we're configuring the underlying openssl / pkcs#11 interface as follows:

httpsAgent = new Agent({
  privateKeyEngine: 'pkcs11',
  privateKeyIdentifier,
  cert: fullCert
})

This worked fine in our development setup, where we had a LetsEncrypt Certificate using 2048 bit RSA key using RSA-PSS as the signature algorithm. We imported the key we got from certbot into the HSM, choosing rsa-sign-pss-2048-sha256 as its signing algorithm and with a key purpose of ASYMMETRIC_SIGNING.

Now in production however, we are required to use a cert from specific CAs (don't ask). We generated a prod key in the HSM directly (so we are unable to extract the private key), used OpenSSL to generate a CSR for the CA but noticed that they do not accept CSR using RSA-PSS.

We had to downgrade the signing algorithm to PKCS v1.5 so that the CA would accept the CSR.

So the CA accepted the CSR, signed the certificate and we set everything up identically to our dev setup: However, we now get the following error when trying to establish a connection:

module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:116

Additionally, the KMS integration by Google logs the following:

returning 0x68 from C_SignInit due to status FAILED_PRECONDITION: at preconditions.cc:47: mechanism 0xd is not permitted for key
returning 0x70 from C_SignInit due to status INVALID_ARGUMENT: at crypter_ops.cc:62: mechanism 0x3 is not valid for operation sign

Now, I'm not really an expert in cryptography, but the way I understood it was:

  • If I use "2048 bit RSA key PKCS#1 v1.5 padding - SHA256 Digest" as the algorithm for the key in Google KMS, and I'm successfully able to generate a CSR using OpenSSL, shouldn't this work the same compared to using "2048 bit RSA key PSS Padding - SHA256 Digest"?

We're using Node v16, Debian 11.6 with OpenSSL 1.1.1n. I've tried to upgrade the PKCS#11 engine to the latest version as well but to no effect.

Is there any flag or config I need to set so that Node/OpenSSL know which mechanism to use? OpenSSL reports that RSA_PKCS is supported by the engine.

答案1

得分: 1

所以,对于任何尝试相同操作的人。我成功地使用opensc中包含的PKCS#11 Spy找到了问题:

30: C_SignInit
[in] hSession = 0xff0ba74ce08430ad
pMechanism->type=CKM_RSA_PSS

我注意到在尝试签名时,它以某种方式选择了错误的签名算法。它使用了CKM_RSA_PSS而不是CKM_RSA_PKCS,但这不是配置的密钥所能支持的。我不确定为什么会这样,也许只是一个配置问题,RSA_PSS是默认选择的,这让它在我们的测试环境中偶然工作了。

我成功地通过向node的https.Agent添加了一些标志来强制正确的行为,具体来说是sigalgs和将最大TLS版本设置为1.2:

httpsAgent = new Agent({
  privateKeyEngine: 'pkcs11',
  privateKeyIdentifier,
  cert,

  maxVersion: 'TLSv1.2', // 使用TLS v1.2最大版本
  sigalgs:'RSA+SHA256' // 选择正确的签名算法
})

这导致OpenSSL使用了正确的签名算法。将TLS版本设置为v1.2也是必要的,但这是一个无关的后续问题(如果有人遇到类似的设置问题,我包含了这个信息以供参考)。

英文:

So, for anyone trying the same thing. I managed to find the issue using the PKCS#11 Spy included in opensc:

30: C_SignInit
[in] hSession = 0xff0ba74ce08430ad
pMechanism->type=CKM_RSA_PSS

I noticed that it somehow selected the wrong signing algorithm when trying to sign. It used CKM_RSA_PSS instead of CKM_RSA_PKCS, but this isn't what the configured key is capable of. I'm not sure why it does that, maybe it was simply a configuration issue and RSA_PSS was the selected default, which made it work by chance in our test environment.

I managed to force the correct behavior by adding some flags to the https.Agent in node, namely sigalgs and setting a the max TLS version to 1.2:

httpsAgent = new Agent({
  privateKeyEngine: 'pkcs11',
  privateKeyIdentifier,
  cert,

  maxVersion: 'TLSv1.2', // use TLS v1.2 max
  sigalgs:'RSA+SHA256' // choose the right signing algorithm
})

This led to OpenSSL using the correct signing algorithm. Setting the TLS version to v1.2 was necessary as well, but it was an unrelated follow-up problem (I included this for completion if someone has a similar setup going on).

huangapple
  • 本文由 发表于 2023年3月3日 17:37:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75625385.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定