2012-04-22 6 views
3

Я много часов оглядывался на Google и Microsoft Crypto API о том, как создать общедоступную и частную пару ключей ECC. В классе ECDiffieHellmanCng (http://msdn.microsoft.com/en-us/library/system.security.cryptography.ecdiffiehellmancng.aspx#Y3081) приведен пример, но я не знаю, как напрямую обращаться к закрытому ключу.Создание закрытого/открытого ключа ECC с родным C#

Для небольшого фона в программе это консольное приложение C# для управления сеансами TrueCrypt, шифрование с предварительным общим ключом AES и шифрование ECDH/AES. Мне нужна функция, чтобы просто создать пару открытого/закрытого ключа для сохранения в файлах, а затем документацию о том, как использовать эти сгенерированные ключи в зашифрованном AES-файле (вместо генерации во время выполнения, как показано в примере). Также я осведомлен обо всех уязвимостях, возникающих при сохранении файлов на жестком диске, но я не беспокоюсь об этом с помощью этой программы, и я рассматриваю возможность обеспечения безопасности двух клиентских компьютеров.

Также обратите внимание, что я не хочу использовать BouncyCastle API.

ответ

2

Elliptic Curve DiffieHellman не является алгоритмом шифрования, это протокол key agreement. По небезопасному каналу он дает вам и другой стороне общий общий секрет. Это часто используется, например, для ключа AES для обеспечения безопасной связи.

При открытии открытого ключа другой стороны вы можете получить полученный общий секретный ключевой материал с вызовом api this. Обратите внимание, что в соответствии с замечаниями section CNG APi выполняет некоторую пост-обработку в производном тайне, поэтому может или не согласуется с тем, что генерирует истинный крипт.

Чтобы получить фактический закрытый ключ (который не является общим секретом), вы можете использовать следующее. Вы можете другой формат экспорт, они перечислены here

using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng()) 
    { 
    // Any code you have specifies the key your using or generates one 
    var privatekey = alice.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob) 
    } 

Примечания вы можете обмотать вверх с ошибкой сказать, что политика экспорта не позволяет экспортировать закрытый ключ. В этом случае вам необходимо создать и пользовательский ключ с политикой, которая позволяет экспортировать

+0

Я, возможно, немного отошел от моего основного вопроса, который состоял в том, как создать общедоступную/частную пару ключей ЕС. По моим текущим знаниям, ECDH работает аналогично RSA, где каждый клиент имеет открытый и закрытый ключ. Инициирующий клиент использует открытый ключ другого для совместного использования симметричного ключа. Второй клиент использует свой закрытый ключ для дешифрования симметричного ключа, который был отправлен ему зашифрованным его закрытым ключом. Я просто не нашел способ получить доступ к государственному и закрытому ключам без использования API Bouncy Castle. –

+0

Ах, я вижу, что вы просите. Как техническая нота, ее не шифрование, потому что вы не можете выбрать переданное значение, его случайный. Я изменил свой ответ, чтобы включить то, что я думаю, делает то, что вы хотели. – imichaelmiers

+0

Я попытался запустить код, и он дал мне ошибку «Запрошенная операция не поддерживается». Затем я использую оператор try/catch, чтобы узнать, была ли это ошибка, о которой вы предупреждали меня, однако, когда я запускаю ее, она как бы пропускает ее как-то - она ​​ничего не возвращает. 'byte [] alicePrivateKey = null; try { alicePrivateKey = alice.Key.Export (CngKeyBlobFormat.Pkcs8PrivateBlob); } catch (CryptographicException e) { Console.WriteLine ("Ошибка:" + e.Message + "\ nSource:" + e.Source); } ' –

10

Я считаю, что это то, что вы ищете? Если да, отметьте как (мой первый!) Ответ :-)

Большая часть этого связана с CngKey, которая может использоваться во многих вариантах.

static void test1() 
    { 
     CngKey k; 

     if (CngKey.Exists("myECDH", CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey)) 
     { 
      k = CngKey.Open("myECDH", CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey); 
     } 
     else 
     { 
      k = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256, "myECDH", new CngKeyCreationParameters 
     { 
      ExportPolicy = CngExportPolicies.AllowPlaintextExport, 
      KeyCreationOptions = CngKeyCreationOptions.MachineKey, 
      KeyUsage = CngKeyUsages.AllUsages, 
      Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider, 
      UIPolicy = new CngUIPolicy(CngUIProtectionLevels.None) 
     }); 
     } 

     byte[] privateBytes = k.Export(CngKeyBlobFormat.EccPrivateBlob); 
     byte[] publicBytes = k.Export(CngKeyBlobFormat.EccPublicBlob); 

     //This: 
     var privateTester1 = 
      new ECDiffieHellmanCng(CngKey.Import(privateBytes, CngKeyBlobFormat.EccPrivateBlob, 
       CngProvider.MicrosoftSoftwareKeyStorageProvider)); 

     //Or that: 
     var privateTester2 = new ECDiffieHellmanCng(k); 
    } 
+1

OP не был замечен для четыре месяца, поэтому не разочаровывайтесь, если он не будет принят. – CodesInChaos

+0

Справка Vampire alert :-) – shawty

+0

@ henrik-n вы могли бы добавить некоторые заметки о том, как частные байты в вашем коде выше будут записаны в файл в формате PEM/ASN.1. Мне нужно создать CSR и попытаться использовать openssl для этого. Могу ли я генерировать CSR с помощью .NET? – dotnetguy