查询可获取OpenSSL中支持X509证书签名的有效密钥算法列表的API
查询可获取OpenSSL中支持X509证书签名的有效密钥算法列表的API
刚好之前折腾过类似的需求,给你梳理下OpenSSL里怎么拿到符合要求的密钥算法NID列表——既能排除HMAC这类不适合X509证书的算法,又能拿到当前安装版本支持的所有合法选项。
首先得明确:我们要找的是可用于X509证书签名的公钥算法,像HMAC属于消息认证码算法,本身就不属于公钥体系,所以只要我们限定遍历公钥算法类型,就能自然排除这类不符合的项。具体可以通过以下几个API组合实现:
第一步,遍历所有注册的公钥算法:用
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_PKEY, callback, arg)这个函数(不同版本可能以宏的形式实现)。它会把所有注册为公钥类型的算法都过一遍,直接跳过HMAC、对称加密这类非对称公钥体系外的算法。第二步,在遍历的回调函数里过滤出支持签名的算法:不是所有公钥算法都能用于证书签名,比如有些可能只用于加密。这时候可以用
EVP_PKEY_can_sign()来判断——先创建一个空的EVP_PKEY结构,设置它的类型为当前遍历到的算法NID,然后调用这个函数检查是否支持签名操作,能通过的就是符合X509证书要求的算法。
给你贴个简单的代码示例参考:
#include <openssl/objects.h> #include <openssl/evp.h> #include <openssl/x509.h> static int collect_valid_pknids(const OBJ_NAME *name, void *arg) { STACK_OF(ASN1_OBJECT) *valid_algs = (STACK_OF(ASN1_OBJECT)*)arg; int nid = OBJ_sn2nid(name->name); // 尝试初始化对应类型的公钥对象 EVP_PKEY *pkey = EVP_PKEY_new(); if (pkey == NULL) return 1; if (EVP_PKEY_set_type(pkey, nid) == 1) { // 检查该公钥算法是否支持签名操作 if (EVP_PKEY_can_sign(pkey)) { ASN1_OBJECT *obj = OBJ_nid2obj(nid); if (obj != NULL) { sk_ASN1_OBJECT_push(valid_algs, obj); } } } EVP_PKEY_free(pkey); return 1; } // 调用示例 int main() { STACK_OF(ASN1_OBJECT) *valid_pknids = sk_ASN1_OBJECT_new_null(); if (valid_pknids == NULL) { // 错误处理 return 1; } // 遍历并收集所有符合要求的公钥算法NID OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_PKEY, collect_valid_pknids, valid_pknids); // 这里可以遍历valid_pknids,输出或处理每个算法 for (int i = 0; i < sk_ASN1_OBJECT_num(valid_pknids); i++) { ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(valid_pknids, i); char buf[128]; OBJ_obj2txt(buf, sizeof(buf), obj, 1); printf("Valid pknid: %s\n", buf); } sk_ASN1_OBJECT_pop_free(valid_pknids, ASN1_OBJECT_free); return 0; }
另外要注意不同OpenSSL版本的兼容性:比如在OpenSSL 3.0+版本引入了provider体系,有些算法可能需要加载对应provider才能被检测到,但上面的方法在默认配置下已经能覆盖绝大多数常用的合法算法(像RSA、ECDSA、DSA这些)。
备注:内容来源于stack exchange,提问作者Graham Leggett
相关产品推荐
相关产品推荐

