Como posso importar uma chave de GNC para a loja de chaves?

Eu gostaria de importar uma chave que foi exportada usando o CngKey.Export(CngKeyBlobFormat.EccPrivateBlob), dar à chave um nome, e tê-lo persistido na loja de chaves. Isto devia ser tão simples, mas não encontrei maneira de o fazer.

Posso usar a CngKey.Crie para criar uma chave chamada, e ela é persistida para a loja de chaves para que eu possa usá-la mais tarde via Gngkey.Abrir. Se eu criá-lo com as opções adequadas, eu posso usar CngKey.Exportar para exportar a chave como um EccPrivateBlob e armazenar que num ficheiro. Mais tarde, posso ler esses bytes de volta do arquivo e usar uma chamada como a seguinte para reimportar a chave:

CngKey key = CngKey.Import(keyBytes,
       CngKeyBlobFormat.EccPrivateBlob);
Isso é bem sucedido, mas produz uma chave efémera sem nome. Como posso fornecer um nome para a chave Como posso criar, para que a chave importada seja armazenada na loja de chaves?
Estou à procura de uma maneira de arquivar uma chave de assinatura ECDsa e mais tarde restaurá-la a um usuário ou PC diferente. Eu não quero deixar o blob privado deitado ao redor e importá-lo cada vez -- Eu quero um administrador para importá-lo apenas uma vez e tê-lo trancado de forma segura na loja de chaves.

Author: babackman, 2016-03-23

2 answers

Finalmente consegui resolver o problema. A questão principal é que os tipos da Microsoft escreveram o código de tal forma que uma importação não irá importar a chave para a loja de chaves, em vez disso você precisa recriar a chave novamente usando os bytes exportados.

O código completo para exportar, importar e testar é o seguinte:

Crie o parâmetro chave do GNC e defina as suas propriedades

[System.Security.Cryptography.CngKeyCreationParameters] $cngKeyParameter =  [System.Security.Cryptography.CngKeyCreationParameters]::new()
$cngKeyParameter.KeyUsage = [System.Security.Cryptography.CngKeyUsages]::AllUsages
$cngKeyParameter.ExportPolicy = [System.Security.Cryptography.CngExportPolicies]::AllowPlaintextExport

$cngKeyParameter.Provider = [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider
$cngKeyParameter.UIPolicy = [System.Security.Cryptography.CngUIPolicy]::new([System.Security.Cryptography.CngUIProtectionLevels]::None)
$cngKeyParameter.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey

#Create Cng Property for Length, set its value and add it to Cng Key Parameter
[System.Security.Cryptography.CngProperty] $cngProperty = [System.Security.Cryptography.CngProperty]::new($cngPropertyName, [System.BitConverter]::GetBytes(2048), [System.Security.Cryptography.CngPropertyOptions]::None)
$cngKeyParameter.Parameters.Add($cngProperty)

#Create Cng Key for given $keyName using Rsa Algorithm
[System.Security.Cryptography.CngKey] $key = [System.Security.Cryptography.CngKey]::Create([System.Security.Cryptography.CngAlgorithm]::Rsa, "MyRsaKey", $cngKeyParameter)

Write-Output "CNG Key : $globalkeyName - Created"

Exportar a chave para um ficheiro

 [System.IO.File]::WriteAllBytes("c:\\user\myusername\\keyexport", $key.Export([System.Security.Cryptography.CngKeyBlobFormat]::GenericPrivateBlob));

Importação

    $importedKeyBlob = [System.IO.File]::readAllBytes("c:\\user\myusername\\keyexport");
   # [System.Security.Cryptography.CngKey] $importedkey = [System.Security.Cryptography.CngKey]::Import($importedKeyBlob, [System.Security.Cryptography.CngKeyBlobFormat]::GenericPrivateBlob, [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider)

       #Create Cng Key Parameter and set its properties
[System.Security.Cryptography.CngKeyCreationParameters] $cngKeyParameter =  [System.Security.Cryptography.CngKeyCreationParameters]::new()
$cngKeyParameter.KeyUsage = [System.Security.Cryptography.CngKeyUsages]::AllUsages
$cngKeyParameter.ExportPolicy = [System.Security.Cryptography.CngExportPolicies]::AllowPlaintextExport

$cngKeyParameter.Provider = [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider
$cngKeyParameter.UIPolicy = [System.Security.Cryptography.CngUIPolicy]::new([System.Security.Cryptography.CngUIProtectionLevels]::None)
$cngKeyParameter.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey

#Create Cng Property for Length, set its value and add it to Cng Key Parameter
[System.Security.Cryptography.CngProperty] $cngProperty = [System.Security.Cryptography.CngProperty]::new($cngPropertyName, [System.BitConverter]::GetBytes(2048), [System.Security.Cryptography.CngPropertyOptions]::None)
$cngKeyParameter.Parameters.Add($cngProperty)

#Create Cng Property for blob, set its value and add it to Cng Key Parameter
[System.Security.Cryptography.CngProperty] $keyBlobProperty = [System.Security.Cryptography.CngProperty]::new([System.Security.Cryptography.CngKeyBlobFormat]::GenericPrivateBlob,$importedKeyBlob , [System.Security.Cryptography.CngPropertyOptions]::None)
$cngKeyParameter.Parameters.Add($keyBlobProperty)

$cngKeyParameter

#Create Cng Key for given $keyName using Rsa Algorithm
[System.Security.Cryptography.CngKey] $key = [System.Security.Cryptography.CngKey]::Create([System.Security.Cryptography.CngAlgorithm]::Rsa, "MyRsaKey", $cngKeyParameter)

$key 
Aqui estão alguns. pontos importantes:
  1. [Sistema.Seguranca.Criptografia.CngKeyBlobFormat]:: Pkcs8PrivateBlob ainda não está funcionando. Eu vi os caras da MS falando sobre o GitHub que eles têm problemas neste formato de mensagem.
  2. O CngKeyBlobformat deve ser o mesmo para exportação e importação senão o código não funcionará com um erro desconhecido
  3. devias gerir o "PowerShell ISE" com direitos de administração

Para testar:

  • cria a chave 'MyRsaKey'
  • teste se a chave existe alguma chave armazenada pela powershell testing dada por baixo do tópico
  • exporta a chave
  • apaga a chave com o seguinte programa powershell
  • teste a chave novamente se ela estiver lá no porta-chaves
  • importar e testar novamente

Teste se a chave está lá no porta-chaves

$isKeyExists = [System.Security.Cryptography.CngKey]::Exists("MyRsaKey", [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider, [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey)
Write-Output "CNG Key Exists :: $isKeyExists"

Apague a chave do armazém de chaves e teste se a chave for removida com sucesso

[System.Security.Cryptography.CngKey] $key = [System.Security.Cryptography.CngKey]::Open($globalkeyName, [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider, [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey)
    $key.Delete()

    $isKeyExists = [System.Security.Cryptography.CngKey]::Exists($globalkeyName, [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider, [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey)
Write-Output "CNG Key Exists :: $isKeyExists"
 1
Author: Riky, 2018-04-28 01:30:32
Como disse com razão, a importação não fornece um keyName e, por isso, cria uma chave efémera. O que tens de fazer é ligar para a CngKey.Criar e fornecer uma vantagem de GNC nos parâmetros de criação contendo a bolha privada:
var myKSP = CngProvider.MicrosoftSoftwareKeyStorageProvider;
var blobType = CngKeyBlobFormat.GenericPrivateBlob;
var keyData = Convert.FromBase64String(privateKey);
const bool MachineKey = false;

if (!CngKey.Exists(keyName, myKSP))
{
    var keyParams = new CngKeyCreationParameters
    {
        ExportPolicy = CngExportPolicies.AllowPlaintextExport,
        KeyCreationOptions = (MachineKey) ? CngKeyCreationOptions.MachineKey : CngKeyCreationOptions.None,
        Provider = myKSP
    };
    keyParams.Parameters.Add(new CngProperty(blobType.Format, keyData, CngPropertyOptions.None));

    var key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams);
}
Podes ficar com a bolha privada assim.
var myKSP = CngProvider.MicrosoftSoftwareKeyStorageProvider;
if (CngKey.Exists(keyName, myKSP))
{
    var key = CngKey.Open(keyName);
    var blobType = CngKeyBlobFormat.GenericPrivateBlob;
    var bytes = key.Export(blobType);

    return Convert.ToBase64String(bytes);
}
 0
Author: Swifty, 2018-06-18 11:38:24