CNG Импорт ключа ECC Pub/Priv из файла

Я пытался найти, как импортировать ключ ECC из файла ЛЮБЫМИ СРЕДСТВАМИ целую вечность. Я безуспешно пытался получить доступ к сертификату ECC из хранилища сертификатов Windows, из файла .p12 и из файла ключа OpenSSL PKCS#8.

Только одна из многих вещей, которые я пробовал, это:

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);

Но никаких описательных сообщений об ошибках не дается, только то, что последняя строка имеет либо invalid parameters, либо, в случае кода выше, An error occurred during encode or decode operation.

Я использую пример программы из MSDN для ECDH и изменили его для использования режима GCM AES. Все это работает нормально, пока я не попытаюсь использовать предварительно сгенерированные ключи ECC вместо тех, которые создаются по умолчанию во время выполнения для примера Microsoft. Я случайным образом пробовал все CngKeyBlobFormat, но, честно говоря, я не могу хорошо его отладить, потому что я не знаю, как эти конкретные форматы выглядят в необработанных данных.

Мой ключ имеет следующий формат, однако я готов использовать любой формат, который будет работать (.p12, Microsoft Store, PKCS # 8 и т. д.).

key.pem

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

Ресурсы

MSDN API и пример: класс ECDiffieHellmanCng

MSDN API: класс CngKey

Блоги MSDN: AES GCM Режим

OpenSSL — создание ключей ECC


person Jim    schedule 14.05.2013    source источник


Ответы (2)


  1. Сгенерируйте ключ ECC в формате PEM с помощью OpenSSL:
& 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-----

Уххх, я разместил закрытый ключ - он сгенерирован, не используется :-)

Файл содержит ключ в формате SEC.1, который 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 и импортировать ключ:

$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
person Daniel Fisher lennybacon    schedule 12.09.2019

Хотя это может быть не единственная проблема, вы не можете просто закодировать ASCII файл PEM, а затем действовать так, как будто это большой двоичный объект, закодированный PKCS # 8. PKCS#8 указан в ASN.1, который обычно кодируется BER/DER. База 64 PEM кодирует эту двоичную кодировку, а затем помещает верхний и нижний колонтитулы вокруг базы 64, чтобы указать тип данных, которые были закодированы.

Обратите внимание, что закодированные параметры, возможно, придется пропустить. Надеюсь, эти параметры присутствуют в кодировке закрытого ключа.

person Maarten Bodewes    schedule 18.06.2013
comment
Извините за позднее добавление, все еще может быть очень сложно заставить CNG импортировать ключи таким образом - если это не сработает, вы можете захотеть декодировать формат PEM (и ключевые части в формате PKCS # 8) самостоятельно. - person Maarten Bodewes; 18.06.2013