The first step also returns the fixed-byte length regardless of padding. The subsequent NCryptEncrypt(), of the two-step process, fails with NTE_INVALID_PARAMETER, except when run with the no padding option, so pks and OAEP options not working at all. Any help would be appreciated.
// ncryptRepro.cpp
const wchar_t* keyName = L"KeyName";
const char* plainData26 = "abcdefghijklmnopqrstuvwxyz";
const char* plainData520 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
BOOL CreateKey(NCRYPT_PROV_HANDLE hCryptProvider);
int wmain()
{
NCRYPT_PROV_HANDLE hCryptProvider ;
NCRYPT_KEY_HANDLE hKey;
SECURITY_STATUS stat;
BCRYPT_OAEP_PADDING_INFO paddingInfo;
char* tOutBuf=NULL;
paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;
paddingInfo.pbLabel = (PUCHAR)"2vGhHgn6lHB0GXUNyJcCuFOKQsu8btzG35EufkBteJzKCAPRXK";
paddingInfo.cbLabel = strlen((char*)paddingInfo.pbLabel);
if (ERROR_SUCCESS != NCryptOpenStorageProvider(
&hCryptProvider,
MS_KEY_STORAGE_PROVIDER,
0
)) {
std::cout << "Error\r\n";
ExitProcess(1);
}
if (CreateKey(hCryptProvider))
ExitProcess(1);
if (ERROR_SUCCESS != (stat = NCryptOpenKey(
hCryptProvider,
&hKey,
keyName,
0,
NCRYPT_SILENT_FLAG
))) {
std::cout << "Error\r\n";
ExitProcess(1);
}
DWORD tResult = 0;
DWORD iLen = strlen(plainData26);
std::cout << "plaintext size(plainData26): " << iLen << std::endl;
if (ERROR_SUCCESS != (stat = NCryptEncrypt(
hKey,
(PBYTE)plainData26,
iLen,
&paddingInfo,
NULL,
0,
&tResult,
NCRYPT_PAD_OAEP_FLAG //NCRYPT_PAD_PKCS1_FLAG
))) {
std::cout << "Error\r\n";
goto exit_clean_up;
}
std::cout << "cipher text buffer size(plainData26): " << (int)tResult << std::endl;
tOutBuf = (char*)HeapAlloc(GetProcessHeap(), 0, tResult );
if (!tOutBuf) {
std::cout << "Error\r\n";
goto exit_clean_up;
}
if (ERROR_SUCCESS != (stat = NCryptEncrypt(
hKey,
(PBYTE)plainData26,
iLen,
&paddingInfo,
(PBYTE)tOutBuf,
(tResult ),
&tResult,
NCRYPT_PAD_OAEP_FLAG
))) {
if (NTE_INVALID_PARAMETER == stat)
std::cout << "Error, NTE_INVALID_PARAMETER.\r\n";
else
std::cout << "Error, encrypting.\r\n";
goto exit_clean_up;
}
std::cout << "cipherText (plainData26): "<< tOutBuf << std::endl;
HeapFree(GetProcessHeap(), 0, tOutBuf);
tResult = 0;
iLen = strlen(plainData520);
std::cout << "plaintext size(plainData520): " << iLen << std::endl;
if (ERROR_SUCCESS != (stat = NCryptEncrypt(
hKey,
(PBYTE)plainData520,
iLen,
&paddingInfo,
NULL,
0,
&tResult,
NCRYPT_PAD_OAEP_FLAG //NCRYPT_PAD_PKCS1_FLAG
))) {
std::cout << "Error\r\n";
goto exit_clean_up;
}
std::cout << "cipher text buffer size(plainData520): " << (int)tResult << std::endl;
tOutBuf = (char*)HeapAlloc(GetProcessHeap(), 0, tResult);
if (!tOutBuf) {
std::cout << "Error\r\n";
goto exit_clean_up;
}
if (ERROR_SUCCESS != (stat = NCryptEncrypt(
hKey,
(PBYTE)plainData520,
iLen,
&paddingInfo,
(PBYTE)tOutBuf,
(tResult),
&tResult,
NCRYPT_PAD_OAEP_FLAG
))) {
if (NTE_INVALID_PARAMETER == stat)
std::cout << "Error, NTE_INVALID_PARAMETER.\r\n";
else
std::cout << "Error, encrypting.\r\n";
goto exit_clean_up;
}
std::cout << "cipherText (plainData520): " << tOutBuf << std::endl;
exit_clean_up:
if (ERROR_SUCCESS != NCryptDeleteKey(
hKey,
0
)) {
std::cout << "Error\r\n";
ExitProcess(1);
}
ExitProcess(0);
}
BOOL CreateKey(NCRYPT_PROV_HANDLE hCryptProvider) {
NCRYPT_KEY_HANDLE hKey;
SECURITY_STATUS stat;
if (ERROR_SUCCESS != (stat = NCryptCreatePersistedKey(
hCryptProvider,
&hKey,
BCRYPT_RSA_ALGORITHM,
keyName,
AT_KEYEXCHANGE,
NCRYPT_OVERWRITE_KEY_FLAG //0
))) {
std::cout << "Error\r\n";
return TRUE;
}
if (ERROR_SUCCESS != (stat = NCryptFinalizeKey(
hKey,
0
))) {
std::cout << "Error." << std::endl;
return TRUE;
}
if (ERROR_SUCCESS != NCryptFreeObject(
hKey
)) {
std::cout << "Error\r\n";
return TRUE;
}
return FALSE;
}