Mbedtls可以使用其mbedtls_x509_crt_verify(...)
函数(link)来验证x509证书。
但是,我有什么:
mbedtls_pk_context
中)。证书的验证没有问题。
但是,如果该证书验证了不同的密钥怎么办?(软件问题和破解尝试的结果可能是什么。)当然,这样的密钥/证书对将无法使用进行tls握手,但我认为不需要为此建立tcp连接。
This source(尽管它是针对openssl脚本的)很有可能使证书密钥匹配验证仅通过模数匹配即可完成。
还有一个mbedtls_pk_verify(...)
函数(ref),但在我看来,它主要使用签名来播放。但是我没有签名,我有证书(pem格式的证书)和我的密钥(我也有pem格式的密钥)。将它们处理为内部mbedtls数据结构(mbedtls_x509_crt
和mbedtls_pk_context
)不是问题,但是我如何验证它们是否匹配?
答案 0 :(得分:1)
正如this security.SE回答所述,如果证书中的公钥和私钥文件中的公钥相同,则验证就足够了。这是因为它是其中唯一的共享信息。
因此,我们需要从mbedtls_pk_content
和mbedtls_x509_cert
中挖掘出公钥并进行比较。
mbedtls对此任务没有常规的API调用,但是可以通过特定于算法的解决方案来完成。步骤如下。假设我们有
mbedtls_x509_cert crt;
mbedtls_pk_context pk;
crt
拥有证书,pk
是我们的公钥-私钥对。
我们从两者中获得了密钥对。对于椭圆曲线密码,它是由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
现在是密钥对,但是只有其公共部分将为非零,因为证书显然没有私有密钥部分。 mbedtls_pk_ec(...)
在我看来像是个宏,因为它不使用指向结构的指针,而是直接使用结构。
然后,我们比较密钥对中的公钥:
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_match = mbedtls_mpi_cmp_mpi(pk_pub_X, crt_pub_X) || mbedtls_mpi_cmp_mpi(pk_pub_Y, crt_pub_Y);
注意:验证证书匹配项不足以验证证书有效性,仅此要求。证书的验证可以通过已经更加愉快和简单的mbedtls_x509_crt_verify(...)
函数来完成。
答案 1 :(得分:1)
我知道这是一个较老的问题,但也许 mbedtls_pk_check_pair 正是您要找的。将您的私钥/公钥对和证书公钥传递给它。
/**
* \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 );