mic*_*ael 1 openssl cryptography pkcs#11 hsm private-key
问题的答案
如何在 PKCS#11 模块上使用私钥而不是 perivate 密钥文件在 OpenSSL 中进行相互身份验证?
非常清楚地解释了使用存储在智能卡或 HSM(硬件安全模块)上而不是普通文件上的私钥建立 SSL 连接所需的步骤。其实我想用python做同样的事情,但首先我必须了解背后的原理。所以暂时忘记python:
假设密钥已经存在于 HSM 上的“SecureToken”下。所以
我首先必须从引擎加载私钥:
EVP_PKEY* key = ENGINE_load_private_key(e, "SecureToken", NULL, &cb_data);
然后必须打电话
SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
现在,我有一个带有 PKCS#11 接口的 HSM,我可以将其作为 openSSL 引擎加载。慢慢地我对原理有了更好的了解,但是,私钥如何离开模块仍然是个谜:为了将私钥始终保存在模块内,这就是我完全使用 HSM 的原因。
具体来说:我从 1) 中调用的返回值中返回什么作为“键”?我无法想象密钥内容是从 HSM 中读出的,因为 PKCS#11 甚至不支持此操作。我还能得到什么?它只是有关HSM 中密钥的元信息而不是密钥本身吗?并且 SSL_CTX * ctx 稍后如何知道,该“密钥”将如何使用?
鉴于 PKCS#11 引擎已正确加载,这是否意味着任何 RSA 函数都会与存储在上下文中的“元密钥信息”一起自动委托给 HSM ?
请确认这个假设或让我知道我错在哪里。
无论如何,我发现了 EVP_PKEY 是什么:
struct evp_pkey_st {
int type;
int save_type;
int references;
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
union {
char *ptr;
# ifndef OPENSSL_NO_RSA
struct rsa_st *rsa; /* RSA */
# endif
# ifndef OPENSSL_NO_DSA
struct dsa_st *dsa; /* DSA */
# endif
# ifndef OPENSSL_NO_DH
struct dh_st *dh; /* DH */
# endif
# ifndef OPENSSL_NO_EC
struct ec_key_st *ec; /* ECC */
# endif
} pkey;
int save_parameters;
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
} /* EVP_PKEY */ ;
Run Code Online (Sandbox Code Playgroud)
这个结构的关键在哪里?如果 2) 中参数的 pkey 尚未从引擎加载(在我根本不使用引擎的情况下)怎么办?
私钥不会离开模块。密文(或哈希)发送给模块进行解密(或签名),返回明文(或签名)。
您拥有的“键”不是编码键参数的大整数集合。相反,它是一个指向处理与模块交互的引擎的指针,该模块安全地包含该信息。
另一方面,关联的证书或公钥可以从模块中导出。这表示私钥的算法和大小,证书可以在字段和扩展中携带额外的元数据。