CryptDecryptMessage在LSA下运行的服务内部执行时返回CRYPT_E_NO_DECRYPT_CERT
我在LocalMachine/My store中创建了一个带有私钥的RSA证书 然后,我用C创建了一个简单的Windows控制台应用程序:CryptDecryptMessage在LSA下运行的服务内部执行时返回CRYPT_E_NO_DECRYPT_CERT,c,windows,service,certificate,cryptoapi,C,Windows,Service,Certificate,Cryptoapi,我在LocalMachine/My store中创建了一个带有私钥的RSA证书 然后,我用C创建了一个简单的Windows控制台应用程序: 通过指纹找到证书 使用CryptEncryptMessage 将缓冲区写入文件 然后我用C编写了一个小型服务应用程序: 读取缓冲区 使用CryptDecryptMessage进行解密 只要服务应用程序不是在本地系统帐户(LSA)下运行,一切正常。在这种情况下,CryptDecryptMessage生成CRYPT\u E\u NO\u DECRYPT\
- 通过指纹找到证书
- 使用
CryptEncryptMessage
- 将缓冲区写入文件
- 读取缓冲区
- 使用
CryptDecryptMessage进行解密
CryptDecryptMessage
生成CRYPT\u E\u NO\u DECRYPT\u CERT(0x8009200C)
。尽管证书位于LocalMachine/My中,但仍然存在这种情况
我试着尽可能地去除代码,但它仍然相当长。我希望有一些旗帜设置我是错误的。或者这是预期的行为?谢谢你看
Windows控制台应用程序
Windows服务应用程序
在调用
CryptAcquireContext
时,您将pszContainer用作NULL
——因此使用默认密钥容器名称。但这在用户和服务之间是不同的。你需要使用具体的名字。不,谢谢你的建议。您的意思是选择任何唯一的容器名称?我在[(上下文)上读了这些评论但是我不清楚它应该被设置为什么。但是你可以通过CertGetCertificateContextProperty
和CertKey\u PROV\u INFO\u PROP\u ID
从Certificate获取CRYPT\u KEY\u PROV\u INFO\u INFO
并使用pwszContainerName、pwszProvName、dwProvType真的你根本不需要调用CryptAcquireContext
在加密中EncryptParams.hCryptProv
-此成员未使用,应设置为NULL。在decrypt中-调用CertOpenSystemStore(hCryptProv,cStore)时出错;
但您需要打开与encrypt-CertOpenStore(CERT\u store\u PROV\u SYSTEM,X509\u ASN\u编码,0,CERT\u SYSTEM\u store\u LOCAL\u MACHINE,L“MY”)中相同的存储
和代码将更加简单。您可以在调用中使用类似的内容CryptAcquireContext
您使用pszContainer作为NULL
-因此使用默认密钥容器名称。但这在用户和服务之间是不同的。您需要使用具体的名称。这里不是0谢谢您的建议。您的意思是选择任何唯一的容器我?我读了[(上下文)上的评论但是我不清楚它应该被设置为什么。但是你可以通过CertGetCertificateContextProperty
和CertKey\u PROV\u INFO\u PROP\u ID
从Certificate获取CRYPT\u KEY\u PROV\u INFO\u INFO
并使用pwszContainerName、pwszProvName、dwProvType真的你根本不需要调用CryptAcquireContext
在加密中EncryptParams.hCryptProv
-此成员未使用,应设置为NULL。在decrypt中-调用CertOpenSystemStore(hCryptProv,cStore)时出错;
但您需要打开与encrypt-CertOpenStore(CERT\u store\u PROV\u SYSTEM,X509\u ASN\u编码,0,CERT\u SYSTEM\u store\u LOCAL\u MACHINE,L“MY”)中相同的存储
而且代码会简单得多你可以
int __cdecl main(int argc, CHAR* argv[])
{
HCERTSTORE hSysStore = NULL;
DWORD err;
PCHAR certThumbprint = "14FE20556FC106DA4C561707ABDFEACEB8CAAC98";
PCERT_CONTEXT pContext = NULL;
BYTE* pbEncryptedBlob = NULL;
DWORD cbEncryptedBlob;
BYTE bPlain[255] = {0};
DWORD cbContent;
strcpy_s(bPlain, sizeof(bPlain)-1, argv[1]);
cbContent = strlen(bPlain)+1;
err = myGetCertFromThumb(CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY", certThumbprint, &hSysStore, &pContext);
if (err != 0)
goto cleanup;
pbEncryptedBlob = malloc(BUF_SZ);
cbEncryptedBlob = BUF_SZ;
/**** code below ****/
err = myEncryptMsg(pContext, bPlain, cbContent, pbEncryptedBlob, &cbEncryptedBlob);
if (err != 0)
goto cleanup;
printf("Encrypted msg size=%d\n", cbEncryptedBlob);
/**** write cbEncryptedBlob to file ****/
cleanup:
if (pbEncryptedBlob)
free(pbEncryptedBlob);
if (pContext)
CertFreeCertificateContext(pContext);
if (hSysStore != NULL)
CertCloseStore(hSysStore, CERT_CLOSE_STORE_CHECK_FLAG);
return(err);
}
DWORD myEncryptMsg(PCERT_CONTEXT pContext, BYTE* pbPlain, DWORD cbPlainszsz, BYTE* pbCipher, DWORD *pcbCiphersz)
{
BOOL rc;
DWORD err;
PCCERT_CONTEXT RecipientCertArray[1];
DWORD EncryptAlgSize;
HCRYPTPROV hCryptProv;
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
DWORD EncryptParamsSize;
rc = CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
NULL, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_FULL, // Need to both encrypt and sign.
0); // No flags needed.
if (rc)
goto keyset_exists;
err = GetLastError();
if (err != NTE_BAD_KEYSET)
goto cleanup;
rc = CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
NULL, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_AES, // Need to both encrypt and sign.
CRYPT_NEWKEYSET); // No flags needed.
if (!rc)
{
err = GetLastError();
goto cleanup;
}
keyset_exists:
RecipientCertArray[0] = pContext;
EncryptAlgSize = sizeof(EncryptAlgorithm);
memset(&EncryptAlgorithm, 0, EncryptAlgSize);
EncryptAlgorithm.pszObjId = szOID_NIST_AES256_CBC;
EncryptParamsSize = sizeof(EncryptParams);
memset(&EncryptParams, 0, EncryptParamsSize);
EncryptParams.cbSize = EncryptParamsSize;
EncryptParams.dwMsgEncodingType = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING);
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;
rc = CryptEncryptMessage(
&EncryptParams,
1,
RecipientCertArray,
pbPlain,
cbPlainszsz,
pbCipher,
pcbCiphersz);
if (!rc)
{
err = GetLastError();
goto cleanup;
}
err = 0;
cleanup:
if(hCryptProv)
CryptReleaseContext(hCryptProv,0);
return(err);
}
BYTE * someRoutineInsideService()
{
DWORD err;
BYTE* pbEncryptedBlob = NULL;
DWORD cbEncryptedBlob;
BYTE* pbDecryptedMessage = NULL;
DWORD cbDecryptedMessage;
pbEncryptedBlob = malloc(BUF_SZ);
cbEncryptedBlob = BUF_SZ;
/**** read pbEncryptedBlob from file ****/
pbDecryptedMessage = malloc(BUF_SZ);
cbDecryptedMessage = BUF_SZ;
/**** code below ****/
err = myDecryptMessage("MY", pbEncryptedBlob, cbEncryptedBlob, pbDecryptedMessage, &cbDecryptedMessage);
if (err != 0)
goto cleanup;
cleanup:
if (pbEncryptedBlob)
free(pbEncryptedBlob);
return(pbDecryptedMessage);
}
DWORD myDecryptMessage(LPSTR cStore, BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecryptedMessage, DWORD *cbDecryptedMessage)
{
HCERTSTORE CertStoreArray[1];
CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
DWORD DecryptParamsSize = sizeof(DecryptParams);
HCRYPTPROV hCryptProv = 0; // CSP handle
HCERTSTORE hStoreHandle = 0;
DWORD err = 0;
BOOL rc;
rc = CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
NULL, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_FULL, // Need to both encrypt and sign.
0); // No flags needed.
if (!rc)
{
err = GetLastError();
goto cleanup;
}
hStoreHandle = CertOpenSystemStore(hCryptProv, cStore);
if (hStoreHandle == NULL)
{
err = GetLastError();
goto cleanup;
}
CertStoreArray[0] = hStoreHandle;
memset(&DecryptParams, 0, DecryptParamsSize);
DecryptParams.cbSize = DecryptParamsSize;
DecryptParams.dwMsgAndCertEncodingType = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING);
DecryptParams.cCertStore = 1;
DecryptParams.rghCertStore = CertStoreArray;
rc = CryptDecryptMessage(
&DecryptParams,
pbEncryptedBlob,
cbEncryptedBlob,
pbDecryptedMessage,
cbDecryptedMessage,
NULL);
if (!rc)
{
err = GetLastError();
/**** returns 0x8009200C (CRYPT_E_NO_DECRYPT_CERT) if service run under LSA ****/
goto cleanup;
}
cleanup:
if(hCryptProv)
rc = CryptReleaseContext(hCryptProv,0);
return(err);
}