Создание частного CngKey(ECDH_P384) из парольной фразы

Контекст: winforms VS 2015, Windows 7, использование библиотеки SecurityDriven Inferno.

Я кодирую автономное приложение, которое создает зашифрованные файлы для отправки в виде вложений электронной почты (таким образом, не используется в контексте клиент-сервер). Файлы сначала шифруются с помощью Inferno(ETM_Transform), а затем отправляются (иногда для сброса пароля) с другим файлом, обрабатывающим обмен ключами DHM.

Открытый ключ каждого пользователя хранится в таблице данных, созданной и сохраняемой приложением, что обеспечивает быстрый доступ во время процесса обмена ключами. Однако для закрытого ключа моя проблема заключается в том, что пользователи (включая меня) предпочли бы воссоздать свой закрытый ключ из фразы-пароля, избавляя от необходимости скрывать ключ, повышая безопасность и переносимость. Поэтому мне нужно будет создать ключ из сохраненного открытого ключа и хешированной фразы-пароля.

Это правильный подход или, возможно, есть лучший для этого конкретного контекста?

Вот очень короткий пример кода, который выдает исключение: «Запрошенная операция не поддерживается». Как мне приступить к импорту данных в ключ?

    internal static void CreateKey(string passPhrase)
    {
        byte[] keyType = new byte[] { 0x45, 0x43, 0x4B, 0x34 };
        byte[] keyLength = new byte[] { 0x30, 0x0, 0x0, 0x0 };            

        CryptoRandom cr = new CryptoRandom(); // rng used for this example
        byte[] prKey = cr.NextBytes(48); // salt+hash passphrase and pass it to the private key part
        byte[] pbKey = cr.NextBytes(96); // the public part, if I understand the format correctly for a cngkey using ECDH_P384
        byte[] blob = Utils.Combine(keyType, keyLength); // same as concat
        blob = Utils.Combine(blob, pbKey, prKey);

        CngKey key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);                        
    }

person Frank    schedule 25.11.2016    source источник


Ответы (2)


Вы не можете случайным образом сгенерировать открытый ключ. Открытый ключ вычисляется из закрытого ключа (и кривой), и вы, вероятно, получите сообщение об ошибке, что а) открытый X не соответствует тому, что ожидается от закрытого ключа, и б) что координата Y неверна для задана координата X.

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

person bartonjs    schedule 26.11.2016

CngKey Большой двоичный объект DHM имеет особый формат, который включает заголовок — это не просто случайный массив байтов. Вам не хватает этого заголовка, поэтому вы получаете исключение. Радуйтесь, что получили исключение, поскольку то, что вы пытаетесь сделать, концептуально неверно. ECDH_P384 не предназначен для того, чтобы каждая случайная комбинация закрытого ключа была действительным/правильным закрытым ключом. Вы не должны генерировать CngKey вручную - оставьте генерацию CngKey соответствующим CngKey методам.

curve25519, с другой стороны, предназначен для того, чтобы любой случайный закрытый ключ был действительным. Вы можете заново изобрести или реализовать Minilock.

person Inferno author    schedule 05.12.2016
comment
Очень поучительный ответ. Я как раз собирался задать вопрос о хранилище закрытых ключей, но я внимательно изучу Minilock и узнаю, что смогу, прежде чем продолжить... - person Frank; 06.12.2016