我如何使用 mbedtls 验证证书是否验证了密钥?
How can I verify with mbedtls, that a cert validates a key?
Mbedtls 可以使用其 mbedtls_x509_crt_verify(...)
函数 (link) 验证 x509 证书。
然而,我有:
- 一对public/private密钥(保存在
mbedtls_pk_context
中)。
- 我从不同来源获得的证书(因此,不能保证它不包含任何可能的智能修改)。
证书验证没有问题。
但是,如果该证书验证了不同的密钥怎么办?(这可能是软件问题和破解尝试的结果。)当然,这样的 key/cert 对将无法进行 tls 握手,但我认为我不需要为此建立 tcp 连接。
This source(尽管它用于 openssl 脚本)使得证书密钥匹配验证可能仅通过模数匹配就可以发生。
还有一个mbedtls_pk_verify(...)
函数(ref),但在我看来,它主要与签名一起玩。但是我没有签名,我有一个证书(以 pem 格式获得)和我的密钥(我也有一个 pem 格式)。将它们处理成内部 mbedtls 数据结构(mbedtls_x509_crt
和 mbedtls_pk_context
)不是问题,但我如何验证它们是否匹配?
正如this security.SE 回答所说,如果证书和私钥文件中的公钥相同,验证就足够了。因为这是他们唯一共有的共享信息。
因此,我们需要从mbedtls_pk_content
和mbedtls_x509_cert
中挖掘出public密钥并进行比较。
mbedtls 没有针对此任务的通用 API 调用,但可以通过特定于算法的解决方案来完成。步骤如下。假设我们有
mbedtls_x509_cert crt;
mbedtls_pk_context pk;
其中 crt
有证书,pk
是我们的 public-私钥对。
我们从两者那里得到了密钥对。在椭圆曲线密码的情况下,它是由 mbedtls_pk_ec(...)
宏完成的。如果是rsa,则需要mbedtls_rsa_context(...)
:
mbedtls_ecp_keypair* crt_pair = mbedtls_pk_ec(crt->pk);
mbedtls_ecp_keypair* pk_pair = mbedtls_pk_ec(*pk);
注意,虽然crt_pair
现在是一个密钥对,但只有public部分是非零的,因为证书显然没有私钥部分。 mbedtls_pk_ec(...)
对我来说似乎是一些类似宏的东西,因为它不使用指向结构的指针,而是直接使用结构。
然后,我们比较密钥对中的public个密钥:
mbedtls_mpi *pk_pub_X = &pk_pair->Q.X;
mbedtls_mpi *pk_pub_Y = &pk_pair->Q.Y;
mbedtls_mpi *crt_pub_X = &crt_pair->Q.X;
mbedtls_mpi *crt_pub_Y = &crt_pair->Q.Y;
在其他算法(RSA)的情况下,这些部分可能会有所不同,但是我们总是需要有一组大数(mbedtls_mpi
),并比较这些大数。
然后,我们使用mbedtls大数功能来比较它们:
bool does_it_differ = mbedtls_mpi_cmp_mpi(pk_pub_X, crt_pub_X) || mbedtls_mpi_cmp_mpi(pk_pub_Y, crt_pub_Y);
注意:验证证书匹配不足以验证证书有效性,它只是验证证书有效性所必需的。证书的验证可以使用已经更加愉快和简单的 mbedtls_x509_crt_verify(...)
函数来完成。
我知道这是一个较旧的问题,但也许 mbedtls_pk_check_pair 就是您要找的问题。将您的 private/public 密钥对和证书 public 密钥传递给它。
/**
* \brief Check if a public-private pair of keys matches.
*
* \param pub Context holding a public key.
* \param prv Context holding a private (and public) key.
*
* \return \c 0 on success (keys were checked and match each other).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
* be checked - in that case they may or may not match.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
* \return Another non-zero value if the keys do not match.
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
Mbedtls 可以使用其 mbedtls_x509_crt_verify(...)
函数 (link) 验证 x509 证书。
然而,我有:
- 一对public/private密钥(保存在
mbedtls_pk_context
中)。 - 我从不同来源获得的证书(因此,不能保证它不包含任何可能的智能修改)。
证书验证没有问题。
但是,如果该证书验证了不同的密钥怎么办?(这可能是软件问题和破解尝试的结果。)当然,这样的 key/cert 对将无法进行 tls 握手,但我认为我不需要为此建立 tcp 连接。
This source(尽管它用于 openssl 脚本)使得证书密钥匹配验证可能仅通过模数匹配就可以发生。
还有一个mbedtls_pk_verify(...)
函数(ref),但在我看来,它主要与签名一起玩。但是我没有签名,我有一个证书(以 pem 格式获得)和我的密钥(我也有一个 pem 格式)。将它们处理成内部 mbedtls 数据结构(mbedtls_x509_crt
和 mbedtls_pk_context
)不是问题,但我如何验证它们是否匹配?
正如this security.SE 回答所说,如果证书和私钥文件中的公钥相同,验证就足够了。因为这是他们唯一共有的共享信息。
因此,我们需要从mbedtls_pk_content
和mbedtls_x509_cert
中挖掘出public密钥并进行比较。
mbedtls 没有针对此任务的通用 API 调用,但可以通过特定于算法的解决方案来完成。步骤如下。假设我们有
mbedtls_x509_cert crt;
mbedtls_pk_context pk;
其中 crt
有证书,pk
是我们的 public-私钥对。
我们从两者那里得到了密钥对。在椭圆曲线密码的情况下,它是由
mbedtls_pk_ec(...)
宏完成的。如果是rsa,则需要mbedtls_rsa_context(...)
:mbedtls_ecp_keypair* crt_pair = mbedtls_pk_ec(crt->pk); mbedtls_ecp_keypair* pk_pair = mbedtls_pk_ec(*pk);
注意,虽然crt_pair
现在是一个密钥对,但只有public部分是非零的,因为证书显然没有私钥部分。 mbedtls_pk_ec(...)
对我来说似乎是一些类似宏的东西,因为它不使用指向结构的指针,而是直接使用结构。
然后,我们比较密钥对中的public个密钥:
mbedtls_mpi *pk_pub_X = &pk_pair->Q.X; mbedtls_mpi *pk_pub_Y = &pk_pair->Q.Y; mbedtls_mpi *crt_pub_X = &crt_pair->Q.X; mbedtls_mpi *crt_pub_Y = &crt_pair->Q.Y;
在其他算法(RSA)的情况下,这些部分可能会有所不同,但是我们总是需要有一组大数(mbedtls_mpi
),并比较这些大数。
然后,我们使用mbedtls大数功能来比较它们:
bool does_it_differ = mbedtls_mpi_cmp_mpi(pk_pub_X, crt_pub_X) || mbedtls_mpi_cmp_mpi(pk_pub_Y, crt_pub_Y);
注意:验证证书匹配不足以验证证书有效性,它只是验证证书有效性所必需的。证书的验证可以使用已经更加愉快和简单的 mbedtls_x509_crt_verify(...)
函数来完成。
我知道这是一个较旧的问题,但也许 mbedtls_pk_check_pair 就是您要找的问题。将您的 private/public 密钥对和证书 public 密钥传递给它。
/**
* \brief Check if a public-private pair of keys matches.
*
* \param pub Context holding a public key.
* \param prv Context holding a private (and public) key.
*
* \return \c 0 on success (keys were checked and match each other).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
* be checked - in that case they may or may not match.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
* \return Another non-zero value if the keys do not match.
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );