导入和导出 RSA/DSA/EC 密钥

https://cran.r-project.org/web/packages/openssl/vignettes/keys.html

openssl包为 R 实现了 libssl 和 libcrypto 的现代接口。它建立EVP在 OpenSSL 1.0 中引入的新 api 之上,并为各种方法和格式提供统一的 API。OpenSSL 支持三种主要的公钥加密系统:

  • RSA:最流行的方法。支持加密和签名。
  • DSA:数字签名算法。主要用于签名,不再流行。
  • ECDSA:椭圆曲线 DSA。通过 Diffie Hellman 支持签名和加密。越来越受欢迎。

对于每种类型,都有几种常见的存储密钥和证书的格式:

  • DER:二进制格式,序列化ASN.1结构
  • PEM:base64 编码的 DER + 标头包裹在===
  • SSH:带有标头的base64单行。仅适用于公钥。
  • JWK:JSON 网络密钥。将关键数据存储在 JSON 对象中

openssl 包会在可能的情况下自动检测格式。然而,能够识别各种格式可能很有用。

DER 格式

DER 是协议使用的标准二进制格式,用于存储和交换密钥和证书。它由一个序列化的 ASN.1结构组成,其中包含密钥的(非常大的)素数。

key <- ec_keygen()
pubkey <- key$pubkey
bin <- write_der(pubkey)
print(bin)
 [1] 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42
[26] 00 04 da 61 31 1b 82 4b b0 6c dc 26 1a 01 ac ed 52 9b 4f e4 4b bd ba 7c 54
[51] 73 de d8 70 3a f7 6d 9d 65 a1 99 d3 49 c1 82 12 b8 64 87 c4 3e 93 43 4a 51
[76] 99 e8 3d fa f4 90 7c 79 40 e2 61 4e 7a 1a 5e 12

要读取 DER 密钥,请使用read_key或。read_pubkey``der = TRUE

read_pubkey(bin, der = TRUE)
[256-bit ecdsa public key]
md5: 5f94a29c35d272497759e613daf69199

用户通常不需要担心密钥的基本素数,但key$data如果您好奇,可以看看。

PEM 格式

在实践中,用户很少遇到 DER,因为它主要是供内部使用的。当人们交换密钥和证书时,他们通常使用 PEM 格式。PEM 只是base64 编码的 DER 数据,加上一个 header。标头标识密钥(可能还有加密)类型。

cat(write_pem(pubkey))
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2mExG4JLsGzcJhoBrO1Sm0/kS726
fFRz3thwOvdtnWWhmdNJwYISuGSHxD6TQ0pRmeg9+vSQfHlA4mFOehpeEg==
-----END PUBLIC KEY-----
cat(write_pem(key, password = NULL))
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCyO7cBFZNDF7K4br
6/U0ttLLPr6OYhNq/vAizt1gW8ahRANCAATaYTEbgkuwbNwmGgGs7VKbT+RLvbp8
VHPe2HA6922dZaGZ00nBghK4ZIfEPpNDSlGZ6D369JB8eUDiYU56Gl4S
-----END PRIVATE KEY-----

PEM 格式允许使用密码保护私钥。R 在读取此类受保护的密钥时会提示您输入密码。

cat(write_pem(key, password = "supersecret"))
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAhWbzyJTPORewICCAAw
DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIW9hmnxd18eMEgZANDMWmhSd/XusS
gZNy0ExQFG6drCIOZ/MA9ifXp+88/z2HT3pshfpkyaSdf7zGSJmsjNEkE0ZDnUId
+dj2tCKopOiCSNd7x9tQh7pbaZzc0HR+XqyZgz2TGl8/esFRh2cvQwwn5UGp7cLK
m8H5iaTCG+m+mJogd3M1ZqQEjCWAmwSqw1BMAe7ry4FhBv0VwHQ=
-----END ENCRYPTED PRIVATE KEY-----

OpenSSH 格式

无论好坏,OpenSSH 使用自定义格式的公钥。这种格式的优点是它适合单行,这对于您的~/.ssh/known_hosts文件来说非常好。私钥没有特殊格式,OpenSSH 也使用 PEM。

str <- write_ssh(pubkey)
print(str)
[1] "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNphMRuCS7Bs3CYaAaztUptP5Eu9unxUc97YcDr3bZ1loZnTScGCErhkh8Q+k0NKUZnoPfr0kHx5QOJhTnoaXhI="

read_pubkey函数将自动检测文件是否包含一个PEMSSH键。

read_pubkey(str)
[256-bit ecdsa public key]
md5: 5f94a29c35d272497759e613daf69199

JSON Web 密钥 (JWK) 格式

最近另一种存储 RSA 或 EC 密钥的格式是 JSON Web Keys (JWK)。JWK 是Javascript 对象签名和加密 (JOSE)规范的一部分。的write_jwkread_jwk功能在其使用一个单独的封装中实现openssl包。

library(jose)
json <- write_jwk(pubkey)
jsonlite::prettify(json)
{
    "kty": "EC",
    "crv": "P-256",
    "x": "2mExG4JLsGzcJhoBrO1Sm0_kS726fFRz3thwOvdtnWU",
    "y": "oZnTScGCErhkh8Q-k0NKUZnoPfr0kHx5QOJhTnoaXhI"
}

来自jose和 的键openssl是相同的。

mykey <- read_jwk(json)
identical(mykey, pubkey)
[1] TRUE
print(mykey)
[256-bit ecdsa public key]
md5: 5f94a29c35d272497759e613daf69199

你可能感兴趣的:(导入和导出 RSA/DSA/EC 密钥)