4  引擎存储密钥

4  引擎存储密钥

本章介绍 crypto 应用程序中对使用存储在加密引擎中的公钥和私钥的支持。

OpenSSL 公开了引擎 API,使之能够为 OpenSSL 实现的一些加密操作插入替代实现。有关详细信息以及如何加载引擎,请参见引擎加载 章节。

引擎可以提供其他任务,例如为私钥或公钥提供存储空间。此类存储可以比普通文件系统更安全。这些技术在本用户指南中未作介绍。这里我们重点介绍如何在这样的引擎中使用存储的私钥或公钥。

存储引擎必须调用 ENGINE_set_load_privkey_functionENGINE_set_load_pubkey_function。请参见 OpenSSL cryptolib 的手册页

OTP/Crypto 要求用户提供有关密钥的两到三项信息。用户使用的应用程序通常处于更高层级,例如在 SSL 中。如果直接使用 crypto 应用程序,则需要

  • 加载一个引擎,请参见有关引擎加载 的章节或参考手册
  • 可用的引擎中的密钥引用。这应该是一个 Erlang 字符串或二进制文件,具体取决于加载的引擎
  • 使用引擎引用、密钥引用和可能需要的密钥密码(如果引擎需要)构造一个 Erlang 映射。有关映射的详细信息,请参见参考手册

此示例演示如何构造在签名操作中使用的密钥引用。实际密钥存储在提示 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>