我有一些加密的私钥和密码,我想在不使用OpenSSL的情况下将其加载到.NET中,但是我很难找到它们的格式和规范。
我可以解析和解码来自PEM的二进制数据,最初我以为我会得到PKCS#8,但事实并非如此。
用于创建它们的OpenSSL命令例如openssl genrsa -des3 -out test.key 2048
,其结果为:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,7EF293A7B0C43A20
bwz7TPBN2Xr6AxW9y7PRkaQjXYOS3bireDgyD0lBfKMqQ9AV2oTNUcrI2MtaquBH
QaK+bZY0XBpviceXPrfl73cFrBLBZM7/QhyxINWvcuJiq/hyHFwkT/kEOPWg3g+B
6hIKnMiKcObrU2BVHzt9kuiAneRZob9KwohvIHKpD15y0b0Gm8djBTXBAMgDbyIR
vvQvOrWcyTGLhZs+xq07Bv+tpl9ben8RJcOLVb/xBiaoucvUA/jzyT4BcaZmeeNZ
+tSR8B4R0/AWvK5nTpHtDA/5VKWdrGy5HZPNqLOzKO9IMY6xbFrNnPs9/EwufZsi
USLQ/U5/4qdJ/uOMuOuzb0IHTbwMYfsi66Dv0tnCkp6Fmd0ZIGSQvXESQebCbSuJ
mSc3XgpbWK9C0WqHt5jwYs6Ta3TTwXw8aeDWAcyyHCfvcQRUoWWPEverqrZ6u9Ub
Q6+50qkrHqK0JLTclVj5ty1doWRmcu9tyKRpzQuULo9MPkJDYAxrzzbOzMEXrOVM
oKgK/lJSjFx2dHkyTA4Puuu8jyAj99tyhuVCr8G13voB3RdgglKuyAtIamaI8gPU
n13ysFtZv60oWbmP3obeRw3GJvuLkBUOkEGXxCaEmqHhSfA20bnXLPO5iGVHLoiI
Uiv0G+9+726A4GIGJBxVq0I1mt9IMXpqopiyuz22v4dKDJ5MHmtqyt3RalRfki6B
yJh51O46duyKedaWK94P9ZOpVdUcxsPMzJ9UmPW+L/r+N/tQlP54deK86Pq73LrS
9UIQ8A2QMylU0BvpXNLg5w08C3mAzKA4h+QBUL0RMe6JCk1wipKzDJ7oeNh0r/EN
JgMAi1Fxra1PjvPRNG7iYBSiyYoO75W8BIBPW0py6v72mzWQ8Dx9kcH+Xdr5vWfW
aagBTwv17zpfcLtuhmT6FVSg0A1iIQHM6TDjhRq+cJxH4ioaLZNHFxCXNhGa5c2g
E4KOtZPdnCubNinCdzZn0B5KNgKkCVSlm4o6bRrfdqrBLzBBlTTA3mkJgxQYbDzW
W6ET5LZTbJkozSi2nRehyLvLV/FUlIKneyRqQdLFksH82/3R+CW0jsGei+qB8XMY
9ssfQ7ccsvzfCHlss/g/v3uKCwOhTZ3yzo2IA16w4hftlw7IwT4jfOF73CRYILg+
C8Iw2+VMGZmEgDdwJt3TdSB95MDY/WJGwCR7fiat1oMP/uhGqhNyuswnZTq/gWMH
rDJfELbv8HAQfYuh2I3/HDmwjyUi8FkWPpbKhcOHQB8pk3zZTERk3NtV6iAYSG+V
rxEIj3yB3zjn5+9QFOEAU6edqigeM1UKdH5jUUc3hi+C4evzR1xbomDp3JQyw0PB
Jlj2tFMhDhj4thmltBKs1ZwUAd7ei7gvgvQq2vJB1zmwxHS/8g83lryOUHU9zQTF
8SObmYEEmUzy7I5CgvKcePQkRqeZD4x4nsf3Q09NvljrXaWGJjLH+Xjzg3h7fR5b
GvrX7EyyEdFwf3z1tcA/VcFnIQptLTDcjlpxou16WaM1F/OVQ/OGNJnG1xHbVwTv
cDNbpyoP5xERAYSp2YpFTVGJG43tcdDhLjZMN7WGHIb4Qc5Gm1JabxPtys2YnLhB
-----END RSA PRIVATE KEY-----
据我所知,base64编码的数据不是有效的DER / ASN,我发现的工具只是说该数据是无效的,包括openssl asn1parse -inform PEM
。我假设这两个“标头”是区别特征,但是格式是什么?常见的值是什么?
RFC 1421似乎将此类标头称为“封装标头”,否则我没有找到它们。
答案 0 :(得分:2)
这是 OpenSSL的“传统”或“旧版” 格式的私钥文件(或多个,取决于您的计数方式之一)。它在系统上的手册页或on the web中的相关例程中进行了记录-尽管在此页面以许多名称重复或符号链接,但名义上为man 3 PEM_{read,write}{,_bio}_{RSA,DSA,EC}PrivateKey
-在“ PEM加密格式”部分中。简而言之,使用从密码派生的密钥(盐等于IV或它的一部分)对数据进行加密(使用选定的对称算法,在此示例中为DES3 aka DESede aka Triple-DES,具有CBC和IV)。不寻常,只有一次迭代,这是很弱的)。使用的基于密码的密钥派生功能EVP_BytesToKey
有自己的手册页。
这不是不是PKCS8 。除了以不同于PKCS8加密(正式称为EncryptedPrivateKeyInfo
)的加密方式之外,您在解密之后(或如果您不进行加密的话,例如{{1没有genrsa
的}}不是PKCS8清除-$cipher
。相反,它是一种算法相关的数据格式。对于RSA,它是PKCS1 appendix A.1.2中定义的格式,对于DSA和EC,它具有此处不相关的其他格式。
OpenSSL 还支持PKCS8私钥文件,无论是明文还是加密的,具有不同的PEM类型:PrivateKeyInfo
和BEGIN/END PRIVATE KEY
,但不 {{ 1}}。对于API,请参见同一手册页。您可以使用
BEGIN/END ENCRYPTED PRIVATE KEY
PKCS8更加标准(并且可以互换)并且更安全,因此建议使用-正如同一手册页在紧接的NOTES部分中所述。
BouncyCastle的 Java 版本支持BEGIN/END {RSA,DSA,EC} PRIVATE KEY
中的OpenSSL PEM格式。我不知道dotnet版本,但可能值得一看。
如果没有,或者您不能使用它,可以通过添加一个几乎固定的标头将(解密的)PKCS1格式转换为PKCS8。用ASN.1的术语来说,PKCS8是一个包装器,其中包含一些元数据以及一个OCTET STRING,其中包含针对RSA的PKCS1编码。我没有一个dotnet解决方案,但是您可以使用我在Algid parse error, not a sequence甚至Converting a string private key to PrivateKey type上的链接列表来适应Java。