Здравствуйте. Есть задача зашифровать некий набор данных (файл) так, чтобы его мог расшифровать любой человек из некоторого списка. В принципе, для этого достаточно знать только открытые ключи адресатов, после чего сформировать сессионный ключ, зашифровать его ими по отдельности, зашифровать файл сессионным ключом и передать всё это дело на хранение. Для расшифровки дстаточно восстановить одним из закрытых ключей сессионный ключ.
Это теория. На практике видится два варианта: использовать CryptEncryptMessage. Судя по всему эта функция как раз для этой задачи, но проблема в том, что на машине, где осуществляется шифрование нет сертификатов, а есть только сами паблик-ключи.
Для стандратного MS-провайдера срабатывает следующее (схематично, для одного адресата):
1.CryptAcquireContext(&hCryptProv, NULL, provider, provType, CRYPT_VERIFYCONTEXT);
2.CryptGenKey(hCryptProv, algEncrypt, CRYPT_EXPORTABLE, &hSKey);
3.CryptImportKey(hCryptProv, pubData, pubLen, 0, 0, &hAKey);
4.CryptExportKey(hSKey, hAKey, SIMPLEBLOB, 0, keyData, &sz);
Для CryptoPro аналогичный код на экспорте выдаёт ошибку NTE_BAD_KEY_STATE.
По документации срабатывает код со следующими изменениями: надо открыть контекст с private-ключом, потом CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hPKey); а потом этот hPKey - в качестве 4-го параметра в CryptImportKey. Вопрос: зачем он там нужен? Ведь в соответствии с этой же документацией при импорте PUBLIC_KEY_BLOB этот параметр ДОЛЖЕН быть 0?
Итак, финальный вопрос: как зашифровать сообщение для нескольких адресатов, не имея их сертификатов и не имея ни одного секретного ключа?