Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C在Windows中使用PFX/P12证书对字符串进行签名_C_Windows_Certificate_Pfx - Fatal编程技术网

使用C在Windows中使用PFX/P12证书对字符串进行签名

使用C在Windows中使用PFX/P12证书对字符串进行签名,c,windows,certificate,pfx,C,Windows,Certificate,Pfx,我目前有一个项目已经使用PFX证书在C#中对我需要的字符串进行了签名,但是,现在,我必须将该项目的一部分转换为C,以使其与其他项目兼容 我在MSDN中找到了这篇文章,它展示了如何通过从windows应用商店加载证书来加密和签名字符串 但是这个例子的结果并不像预期的那样,因为在我的例子中,我只需要对字符串进行签名,而不需要加密和签名,我检查了是否有只需要签名的函数,但是我没有找到 另一点,我如何加载.PFX/.P12文件,并将其与windows功能一起使用,而不必在计算机上安装证书 我在C#中对字

我目前有一个项目已经使用PFX证书在C#中对我需要的字符串进行了签名,但是,现在,我必须将该项目的一部分转换为C,以使其与其他项目兼容

我在MSDN中找到了这篇文章,它展示了如何通过从windows应用商店加载证书来加密和签名字符串

但是这个例子的结果并不像预期的那样,因为在我的例子中,我只需要对字符串进行签名,而不需要加密和签名,我检查了是否有只需要签名的函数,但是我没有找到

另一点,我如何加载.PFX/.P12文件,并将其与windows功能一起使用,而不必在计算机上安装证书

我在C#中对字符串进行签名的方法如下:


类的
Encode
函数在内部使用
wincrypt.h
库,并调用方法和

Microsoft文档还包含完整的

#pragma注释(lib,“crypt32.lib”)
#包括
#包括
#包括
#定义MY_ENCODING_类型(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
无效MyHandleError(字符*s);
真空总管(真空)
{
//-------------------------------------------------------------------
//版权所有(C)Microsoft。保留所有权利。
//声明和初始化变量。
BYTE*pbContent=(BYTE*)“安全是我们唯一的业务。”;
//字节指针
DWORD cbContent=strlen((char*)pbContent)+1;
//消息的大小
hCertStorehStoreHandle;
HCRYPTPROV HCRYPTPROV;
PCCERT\u CONTEXT pSignerCert;//签名者的证书
PCCERT\u CONTEXT pRecipCert;//接收方证书
LPWSTR pswzRecipientName=L“Hortense”;
LPWSTR pswzCertSubject=L“完整测试证书”;
PCERT_信息RecipCertArray[1];
DWORD ContentEncryptAlgSize;
加密算法;
CMSG_信封_编码_信息信封编码信息;
DWORD cbEncodedBlob;
字节*pbEncodedBlob;
德沃德·cbSignedBlob;
字节*pbSignedBlob;
HCRYPTMSG;
德沃德·哈沙尔格西兹;
密码算法;
CMSG_签名者_编码_信息签名者代码信息;
证书签名者;
CERT_BLOB SignerCertBlobaray[1];
CMSG_签名者_编码_信息签名者代码信息数组[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
//-------------------------------------------------------------------
//开始处理。显示原始消息。
printf(“原始消息=>%s\n”,pbContent);
//-------------------------------------------------------------------
//获取加密提供程序。
如果(加密)上下文(
&hCryptProv,//要返回的句柄的地址
NULL,//使用当前用户的登录名
NULL,//使用默认提供程序
PROV\u RSA\u FULL,//提供程序类型
0))//零允许访问私钥
{
printf(“已获取上下文CSP。\n”);
}
其他的
{
如果(GetLastError()==NTE\u坏键集)
{
printf(“未找到可用的私钥\n”);
printf(“在默认密钥容器中。a\n”);
printf(“必须在该容器中生成私钥\n”);
printf(“可以使用CryptAquireCertificatePrivateKey\n”);
printf(“获取所需私钥的访问权”);
}
MyHandleError(“CryptAcquireContext失败”);
}
//-------------------------------------------------------------------
//打开“我的系统”证书存储。
if(hStoreHandle=CertOpenStore(
证书存储证明系统,
0,
无效的
证书系统存储当前用户,
(我的)
{
printf(“我的系统存储已打开。\n”);
}
其他的
{
MyHandleError(“获取存储句柄时出错”);
}
//-------------------------------------------------------------------
//获取签名者的证书。此证书必须位于
//我的存储,并且其私钥必须可用。
如果(pSignerCert=CertFindCertificateInstaller)(
hStoreHandle,
我的编码类型,
0,
证书查找主题,
pswzcert主题,
空)
{
printf(“找到%S的证书。\n”,pswzCertSubject);
}
其他的
{
MyHandleError(“未找到签名者证书”);
}
//-------------------------------------------------------------------
//初始化算法标识符结构。
HashAlgSize=sizeof(HashAlgorithm);
memset(&HashAlgorithm,0,HashAlgSize);//初始化为零
HashAlgorithm.pszObjId=szOID\u RSA\u MD5;//初始化
//必要成员
//-------------------------------------------------------------------
//初始化CMSG\u签名者\u编码\u信息结构。
memset(&SignerEncodeInfo,0,sizeof(CMSG\u SIGNER\u ENCODE\u INFO));
SignerEncodeInfo.cbSize=sizeof(CMSG\u SIGNER\u ENCODE\u INFO);
SignerEncodeInfo.pCertInfo=pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv=hCryptProv;
SignerEncodeInfo.dwKeySpec=AT_keychange;
SignerEncodeInfo.HashAlgorithm=HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo=NULL;
//-------------------------------------------------------------------
//创建一个数组。
//注意:当前程序仅为单个签名者设置。
SignerEncodeInfoArray[0]=SignerEncodeInfo;
//-------------------------------------------------------------------
//初始化CMSG\u签名\u编码\u信息结构。
SignerCertBlob.cbData=pSignerCert->cbCertEncoded;
SignerCertBlob.pbData=pSignerCert->pbCertEncoded;
//-------------------------------------------------------------------
//初始化一个CertBlob的数组。
SignerCertBlobArray[0]=SignerCertBlob;
memset(&SignedMsgEncodeInfo,0,sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize=sizeof(CMSG\u SIGNED\u ENCODE\u INFO);
SignedMsgEncodeInfo.cSigners=1;
SignedMsgEncodeInfo.rgSigners=SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded=1;
SignedMsgEncodeInfo.rgCertEncoded=SignerCertBlobArray;
SignedMsgEncodeInfo
    public byte[] SignString(string mensagem)
    {
        var certificado = SearchCertificate();
        CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificado);
        signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1"); //SHA256

        ContentInfo content = new ContentInfo(new Oid(Configuration.ContentOid), new System.Text.UTF8Encoding().GetBytes(mensagem));
        SignedCms signedCms = new SignedCms(content, false);

        signedCms.ComputeSignature(signer, false);
        var signedStringBytes = signedCms.Encode();

        return signedStringBytes;
    }