查看源代码 引擎存储密钥
本章介绍 crypto 应用程序中对使用存储在加密引擎中的公钥和私钥的支持。
背景
OpenSSL 公开了一个引擎 API,使得可以插入 OpenSSL 实现的某些加密操作的替代实现。有关详细信息以及如何加载引擎,请参阅 引擎加载 一章。
引擎可以执行其他任务,例如为私钥或公钥提供存储。这种存储可以比普通文件系统更安全。这些技术在本用户指南中没有描述。这里我们专注于如何使用存储在这种引擎中的私钥或公钥。
存储引擎必须调用 ENGINE_set_load_privkey_function
和 ENGINE_set_load_pubkey_function
。请参阅 OpenSSL 加密库的 手册页。
OTP/Crypto 要求用户提供关于密钥的两到三项信息。用户使用的应用程序通常在更高的层级,例如在 SSL 中。如果直接使用 crypto 应用程序,则需要:
- 加载一个引擎,请参阅关于 引擎加载 的章节或 参考手册
- 可以使用引擎中密钥的引用。这应该是一个 Erlang 字符串或二进制,具体取决于加载的引擎
- 构造一个 Erlang map,其中包含引擎引用、密钥引用,如果引擎需要,可能还包含密钥密码短语。有关 map 的详细信息,请参阅 参考手册。
使用场景
使用引擎存储的私钥签名
此示例显示如何构造用于签名操作的密钥引用。实际密钥存储在提示 1 加载的引擎中。
1> {ok, EngineRef} = crypto:engine_load(....).
...
{ok,#Ref<0.2399045421.3028942852.173962>}
2> PrivKey = #{engine => EngineRef,
key_id => "id of the private key in Engine"}.
...
3> Signature = crypto:sign(rsa, sha, <<"The message">>, PrivKey).
<<65,6,125,254,54,233,84,77,83,63,168,28,169,214,121,76,
207,177,124,183,156,185,160,243,36,79,125,230,231,...>>
使用引擎存储的公钥验证
在此,使用公钥验证上一个示例中的签名和消息。公钥存储在引擎中,只是为了示例说明这是可行的。公钥当然可以像往常一样公开处理。
4> PublicKey = #{engine => EngineRef,
key_id => "id of the public key in Engine"}.
...
5> crypto:verify(rsa, sha, <<"The message">>, Signature, PublicKey).
true
6>
使用受密码保护的私钥
与第一个签名示例相同,只是密码保护了引擎中的密钥。
6> PrivKeyPwd = #{engine => EngineRef,
key_id => "id of the pwd protected private key in Engine",
password => "password"}.
...
7> crypto:sign(rsa, sha, <<"The message">>, PrivKeyPwd).
<<140,80,168,101,234,211,146,183,231,190,160,82,85,163,
175,106,77,241,141,120,72,149,181,181,194,154,175,76,
223,...>>
8>