Amir Dashti Ответов: 1

Ncryptdecrypt не удается расшифровать данные, зашифрованные openssl с помощью RSA_PKCS1_OAEP_PADDING


Мне трудно расшифровать данные, зашифрованные с помощью OpenSSL, RSA и RSA_PKCS1_OAEP_PADDING padding option.

То, что я делаю, это загрузить ключ из Windows KSP:
m_hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, m_storeName.c_str());

m_pCertWithKeys = CertFindCertificateInStore(m_hSystemStore, SupportedEncodings, 0, CERT_FIND_SUBJECT_STR, m_certName.c_str(), NULL);

// Obtain the private key from the certificate.
DWORD m_KeyContextSpec = 0;
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE m_hKeyContextFull;
CryptAcquireCertificatePrivateKey(m_pCertWithKeys, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG, NULL, &m_hKeyContextFull, &m_KeyContextSpec, &m_KeyContextMustBeReleased);

и вызовите NCryptDecrypt как:
BCRYPT_OAEP_PADDING_INFO paddingInfo = { 0 };
DWORD cbDecryptedMessage;
BYTE* pbDecryptedMessage = NULL;

paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;

// Calculate the required buffer
NCryptDecrypt(m_hKeyContextFull, (LPBYTE)pEncrypted, encryptedLenInBytes, &paddingInfo, NULL, cbDecryptedMessage, &outputDataLen, NCRYPT_PAD_OAEP_FLAG | NCRYPT_SILENT_FLAG);

// After required buffer is allocated...
NCryptDecrypt(m_hKeyContextFull, (LPBYTE)pEncrypted, encryptedLenInBytes, &paddingInfo, pbDecryptedMessage, cbDecryptedMessage, &outputDataLen, NCRYPT_PAD_OAEP_FLAG | NCRYPT_SILENT_FLAG);

Он не работает с NTE_INVALID_PARAMETER (0x80090027). Я пробовал разные флаги, но ни один из них не работает.

Примечание: все проверки ошибок были удалены из кода для удобства чтения.

Данные шифруются с помощью того же ключа (публичная часть), что и:
RsaPublicEncrypt(size - 42, blk, output, Rsa, RSA_PKCS1_OAEP_PADDING)

и может быть успешно расшифрован с помощью Softsm.

Есть ли какие-либо ограничения для CNG для расшифровки данных, зашифрованных OpenSSL?
Есть ли какая-нибудь идея, что я делаю не так?

Спасибо.

Что я уже пробовал:

Я ничего не менял в стороне OpenSSL, потому что эта часть работает, и мы можем расшифровать данные с помощью Softsm с тем же ключом, но:
* Я пробовал разные флаги в NCryptDecrypt
* Другой алгоритм заполнения
* Другой алгоритм для генерации ключа
Ни один из них не работал до сих пор.

1 Ответов

Рейтинг:
1

Jochen Arndt

Вы должны были показать полный код. Так что я могу только догадываться, что вы, возможно, забыли инициализировать cbDecryptedMessage перед вызовом NCryptDecrypt():

pbDecryptedMessage = new BYTE[outputDataLen]; // or malloc() with C
cbDecryptedMessage = outputDataLen;


Amir Dashti

Спасибо за ответ, буфер выделяется с помощью вызова функции malloc (). Я просто удалил эту часть и упомянул ее в качестве комментария в примере кода.

Jochen Arndt

Да, я видел и понимаю этот комментарий.

Но устанавливаете ли вы cbDecryptedMessage в не опубликованном коде?

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

И эти параметры-cbDecryptedMessage и pbDecryptedMessage; единственные, которые не показаны для инициализации в вашем опубликованном коде!

Amir Dashti

Вы совершенно правы, мои извинения, даже первый звонок не удался...

Jochen Arndt

Чем это, скорее всего, pEncrypted и/или encryptedLenInBytes, потому что paddingInfo выглядит нормально, недопустимый дескриптор вернет NTE_INVALID_HANDLE, а недопустимый флаг вернет NTE_BAD_FLAGS.

Так что проверь их.