c# - CNG 从文件导入 ECC 公钥/私钥

标签 c# cryptography elliptic-curve cng aes-gcm

多年来,我一直在尝试寻找如何通过任何方式从文件中导入 ECC key 。我曾尝试从 Windows 证书存储、.p12 文件和 PKCS#8 OpenSSL key 文件访问 ECC 证书,但均未成功。

我尝试过的许多事情之一是:

StreamReader fs = new StreamReader("key.pem");
String key = fs.ReadToEnd();
byte[] tempkey = System.Text.Encoding.ASCII.GetBytes(key);
CngKey cngKey = CngKey.Import(tempkey, CngKeyBlobFormat.Pkcs8PrivateBlob);

但是没有给出描述性的错误消息,只有最后一行有无效参数,或者在上述代码的情况下,在编码或解码操作期间发生错误。

我正在使用 sample program来自 MSDN 的 ECDH 和 altered it使用 AES 的 GCM 模式。在我尝试使用预生成的 ECC key 而不是 Microsoft 示例在运行时默认创建的 key 之前,所有这些都工作正常。我随机尝试了所有的 CngKeyBlobFormat,但老实说,我不能很好地调试它,因为我不知道这些特定格式在原始数据中是什么样子。

我的 key 采用以下格式,但我愿意使用任何可行的格式(.p12、Microsoft Store、PKCS#8 等)

key .pem

-----BEGIN EC PARAMETERS-----
##############################
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
##############################
-----END EC PRIVATE KEY-----

资源

MSDN API and Example: ECDiffieHellmanCng Class

MSDN API: CngKey Class

MSDN Blogs: AES GCM Mode

OpenSSL - Creating ECC keys

最佳答案

  1. 使用 OpenSSL 生成 PEM 格式的 ECC key :
& openssl ecparam -name "secp521r1" -genkey -param_enc explicit -out ".\private.key"

文件内容为:

-----BEGIN EC PARAMETERS-----
MIIBwwIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////
//////////////////////////////////////////////////8wgZ8EQgH/////
////////////////////////////////////////////////////////////////
/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ
4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8AAxUA0J6IACkcuFOWzGcX
OTKEqqDaZLoEgYUEAMaFjga3BATpzZ4+y2YjlbRCnGSBOQU/tSH4KK9ga009uqFL
Xnfv51ko/h3BJ6L/qN4zSLPBhWpCm/l+fjHC5b1mARg5KWp4mjvABFyKX7QsfRvZ
mPVESVebRGgXr70XJz5mLJfucple9CZAxVC5AT+tB2E1PHCGonLCQIi+lHaf0WZQ
AkIB///////////////////////////////////////////6UYaHg78vlmt/zAFI
9wml0Du1ybiJnEeuu2+3HpE4ZAkCAQE=
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIICngIBAQRCABEwHYVa214LUODzm4BXWkBFSTBDU/N/nNwTB/mAP1Khpn0vd0QH
b/8BrfMbUYzzWXtXsvRvxPzKB2Sc6s7JC8CfoIIBxzCCAcMCAQEwTQYHKoZIzj0B
AQJCAf//////////////////////////////////////////////////////////
////////////////////////////MIGfBEIB////////////////////////////
//////////////////////////////////////////////////////////wEQgBR
lT65YY4cmh+SmiGgtoVA7qLacluZsxXzuLSJkY7xCeFWGTlR7H6TexZSwL07sb8H
NXPfiD0sNPHvRR/Ua1A/AAMVANCeiAApHLhTlsxnFzkyhKqg2mS6BIGFBADGhY4G
twQE6c2ePstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0iz
wYVqQpv5fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX
7nKZXvQmQMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////
////////////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6R
OGQJAgEBoYGJA4GGAAQAIzBvnlURokMqtUyYrOJ5Kd1Mz0/7xGXkbhOR4ReIt9mt
hsL2tK3PQWj/j28IEajPRbVtxxA7McxQfayY9vUKdF8A6+qkOBCji82nKwKyu2+9
7l5FowAW05SdWRgJnqHU5ENf2h3Hje5UH1AidcpDZgTDuCV263PRKCUqUwX+LRN3
t7Y=
-----END EC PRIVATE KEY-----

Uhhhh 我发布了一个私钥 - 这是一个未使用的生成的 :-)

该文件包含 SEC.1 格式的 key ,Cng 无法导入。所以我们将其转换为 PKCS#8:

& openssl pkcs8 -topk8 -inform pem -in ".\private.key" -outform PEM -nocrypt -out ".\private_plain.p8"

这是 PKCS#8 的内容:

-----BEGIN PRIVATE KEY-----
MIICsAIBADCCAdAGByqGSM49AgEwggHDAgEBME0GByqGSM49AQECQgH/////////
////////////////////////////////////////////////////////////////
/////////////zCBnwRCAf//////////////////////////////////////////
///////////////////////////////////////////8BEIAUZU+uWGOHJofkpoh
oLaFQO6i2nJbmbMV87i0iZGO8QnhVhk5Uex+k3sWUsC9O7G/BzVz34g9LDTx70Uf
1GtQPwADFQDQnogAKRy4U5bMZxc5MoSqoNpkugSBhQQAxoWOBrcEBOnNnj7LZiOV
tEKcZIE5BT+1Ifgor2BrTT26oUted+/nWSj+HcEnov+o3jNIs8GFakKb+X5+McLl
vWYBGDkpaniaO8AEXIpftCx9G9mY9URJV5tEaBevvRcnPmYsl+5ymV70JkDFULkB
P60HYTU8cIaicsJAiL6Udp/RZlACQgH/////////////////////////////////
//////////pRhoeDvy+Wa3/MAUj3CaXQO7XJuImcR667b7cekThkCQIBAQSB1jCB
0wIBAQRCABEwHYVa214LUODzm4BXWkBFSTBDU/N/nNwTB/mAP1Khpn0vd0QHb/8B
rfMbUYzzWXtXsvRvxPzKB2Sc6s7JC8CfoYGJA4GGAAQAIzBvnlURokMqtUyYrOJ5
Kd1Mz0/7xGXkbhOR4ReIt9mthsL2tK3PQWj/j28IEajPRbVtxxA7McxQfayY9vUK
dF8A6+qkOBCji82nKwKyu2+97l5FowAW05SdWRgJnqHU5ENf2h3Hje5UH1AidcpD
ZgTDuCV263PRKCUqUwX+LRN3t7Y=
-----END PRIVATE KEY-----

未读取 PKCS#8 并导入 key :

$bytes = [Convert]::FromBase64String(
  [String]::Join(
    [String]::Empty, 
    ([IO.File]::ReadAllLines(".\private_plain.p8") `
      | Where-Object { $_.StartsWith("-") -ne $true })));

$key = [System.Security.Cryptography.CngKey]::Import(
  $bytes, 
  [System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob);

Write-Host $key.Algorithm

关于c# - CNG 从文件导入 ECC 公钥/私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16553225/

相关文章:

c# - 使用 ExpertPDF/Aspose.Pdf 组件将 Html 转换为 PDF 需要很长时间

c# - Fluent NHibernate 组件映射问题

c# - 内部有两个服务和依赖注入(inject)的外观 - 设计模式方法

c# - EF .NET Core2 第一次加载需要更多时间

c++ - C++中的简单加密/解密

javascript - crypto-js 输出与 Node 加密不同

java - 在没有第三方库的情况下,Java 7 能做基本的 EC 操作吗?

java - 如何验证由 ECDSA [r, s] 值组成的 openssl 中的签名?

java - 最近的 Java 升级导致椭圆曲线服务器证书的 TLS 握手失败?

python-2.7 - Python——用于椭圆曲线的 Matplotlib 与 sympy solve()