- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前有一个项目已经使用 PFX 证书在 C# 中签署了我需要的字符串,但是现在,我必须将该项目的部分内容转换为 C,以使其与其他项目兼容...
我在MSDN中找到这篇文章https://learn.microsoft.com/en-us/windows/win32/seccrypto/example-c-program-signing-a-message-and-verifying-a-message-signature它显示了如何通过从 Windows 存储加载证书来加密和签署字符串......
但是这个例子的结果并不符合预期,因为在我的例子中我只需要对字符串进行签名而不是加密和签名,我检查了是否有任何只签名的函数,但我没有找到.. .
还有一点,如何加载 .PFX/.P12 文件,并将其与 Windows 功能一起使用,而不必在计算机上安装证书...
我在 C# 中对字符串进行签名的方法是这样的:
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;
}
最佳答案
Encode
SignedCms
的功能类使用 wincrypt.h
库内部并调用方法 CryptMsgOpenToEncode
, CryptMsgUpdate
和 CryptMsgGetParam
.
Microsoft 文档还包含完整的 example
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
void main(void)
{
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Declare and initialize variables.
BYTE* pbContent = (BYTE*) "Security is our only business.";
// a byte pointer
DWORD cbContent = strlen((char *) pbContent)+1;
// the size of the message
HCERTSTORE hStoreHandle;
HCRYPTPROV hCryptProv;
PCCERT_CONTEXT pSignerCert; // signer's certificate
PCCERT_CONTEXT pRecipCert; // receiver's certificate
LPWSTR pswzRecipientName = L"Hortense";
LPWSTR pswzCertSubject = L"Full Test Cert";
PCERT_INFO RecipCertArray[1];
DWORD ContentEncryptAlgSize;
CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;
CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
DWORD cbEncodedBlob;
BYTE *pbEncodedBlob;
DWORD cbSignedBlob;
BYTE *pbSignedBlob;
HCRYPTMSG hMsg;
DWORD HashAlgSize;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
//-------------------------------------------------------------------
// Begin processing. Display the original message.
printf("The original message => %s\n",pbContent);
//-------------------------------------------------------------------
// Acquire a cryptographic provider.
if(CryptAcquireContext(
&hCryptProv, // address for handle to be returned
NULL, // use the current user's logon name
NULL, // use the default provider
PROV_RSA_FULL, // provider type
0)) // zero allows access to private keys
{
printf("Context CSP acquired. \n");
}
else
{
if ( GetLastError() == NTE_BAD_KEYSET)
{
printf("A Usable private key was not found \n");
printf("in the default key container. Either a \n");
printf("private key must be generated in that container \n");
printf("or CryptAquireCertificatePrivateKey can be used \n");
printf("to gain access to the needed private key.");
}
MyHandleError("CryptAcquireContext failed.");
}
//-------------------------------------------------------------------
// Open the My system certificate store.
if(hStoreHandle = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))
{
printf("The MY system store is open. \n");
}
else
{
MyHandleError( "Error getting store handle.");
}
//-------------------------------------------------------------------
// Get the signer's certificate. This certificate must be in the
// My store, and its private key must be available.
if(pSignerCert = CertFindCertificateInStore(
hStoreHandle,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
pswzCertSubject,
NULL))
{
printf("Found certificate for %S.\n",pswzCertSubject);
}
else
{
MyHandleError("Signer certificate not found.");
}
//-------------------------------------------------------------------
// Initialize the algorithm identifier structure.
HashAlgSize = sizeof(HashAlgorithm);
memset(&HashAlgorithm, 0, HashAlgSize); // initialize to zero
HashAlgorithm.pszObjId = szOID_RSA_MD5; // initialize the
// necessary member
//-------------------------------------------------------------------
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.
memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;
//-------------------------------------------------------------------
// Create an array of one.
// Note: The current program is set up for only a single signer.
SignerEncodeInfoArray[0] = SignerEncodeInfo;
//-------------------------------------------------------------------
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.
SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;
//-------------------------------------------------------------------
// Initialize the array of one CertBlob.
SignerCertBlobArray[0] = SignerCertBlob;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;
//-------------------------------------------------------------------
// Get the size of the encoded, signed message BLOB.
if(cbSignedBlob = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE, // message encoding type
0, // flags
CMSG_SIGNED, // message type
&SignedMsgEncodeInfo, // pointer to structure
NULL, // inner content OID
cbContent)) // size of content
{
printf("%d, the length of data calculated. \n",cbSignedBlob);
}
else
{
if ( GetLastError() == NTE_BAD_KEYSET)
{
printf("A Usable private key was not found \n");
printf("in the default key container. Either a \n");
printf("private key must be generated in that container \n");
printf("or CryptAquireCertificatePRivateKey can be used \n");
printf("to gain access to the needed private key.");
}
MyHandleError("Getting cbSignedBlob length failed.");
}
//-------------------------------------------------------------------
// Allocate memory for the encoded BLOB.
if(pbSignedBlob = (BYTE *) malloc(cbSignedBlob))
{
printf("Memory has been allocated for the signed message. \n");
}
else
{
MyHandleError("Memory allocation failed.");
}
//-------------------------------------------------------------------
// Open a message to encode.
if(hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_SIGNED, // message type
&SignedMsgEncodeInfo, // pointer to structure
NULL, // inner content OID
NULL)) // stream information (not used)
{
printf("The message to be encoded has been opened. \n");
}
else
{
MyHandleError("OpenToEncode failed.");
}
//-------------------------------------------------------------------
// Update the message with the data.
if(CryptMsgUpdate(
hMsg, // handle to the message
pbContent, // pointer to the content
cbContent, // size of the content
TRUE)) // last call
{
printf("Content has been added to the encoded message. \n");
}
else
{
MyHandleError("MsgUpdate failed.");
}
//-------------------------------------------------------------------
// Get the resulting message.
if(CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
pbSignedBlob, // pointer to the BLOB
&cbSignedBlob)) // size of the BLOB
{
printf("Message encoded successfully. \n");
}
else
{
MyHandleError("MsgGetParam failed.");
}
//-------------------------------------------------------------------
// pbSignedBlob now points to the encoded, signed content.
//-------------------------------------------------------------------
// Get a pointer to the recipient certificate.
// For this program, the recipient's certificate must also be in the
// My store. At this point, only the recipient's public key is needed.
// To open the enveloped message, however, the recipient's
// private key must also be available.
if(pRecipCert=CertFindCertificateInStore(
hStoreHandle,
MY_ENCODING_TYPE, // use X509_ASN_ENCODING
0, // no dwFlags needed
CERT_FIND_SUBJECT_STR, // find a certificate with a
// subject that matches the
// string in the next parameter
pswzRecipientName, // the Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// in all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("Certificate for %S found. \n", pswzRecipientName);
}
else
{
MyHandleError("Could not find the countersigner's "
"certificate.");
}
//-------------------------------------------------------------------
// Initialize the first element of the array of CERT_INFOs.
// In this example, there is only a single recipient.
RecipCertArray[0] = pRecipCert->pCertInfo;
//-------------------------------------------------------------------
// Initialize the symmetric-encryption algorithm identifier
// structure.
ContentEncryptAlgSize = sizeof(ContentEncryptAlgorithm);
memset(&ContentEncryptAlgorithm,
0,
ContentEncryptAlgSize); // initialize to zero
//-------------------------------------------------------------------
// Initialize the necessary members. This particular OID does not
// need any parameters. Some OIDs, however, will require that
// the other members be initialized.
ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC4;
//-------------------------------------------------------------------
// Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.
memset(&EnvelopedEncodeInfo,
0,
sizeof(CMSG_ENVELOPED_ENCODE_INFO));
EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
EnvelopedEncodeInfo.hCryptProv = hCryptProv;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm =
ContentEncryptAlgorithm;
EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
EnvelopedEncodeInfo.cRecipients = 1;
EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;
//-------------------------------------------------------------------
// Get the size of the encoded message BLOB.
if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE, // message encoding type
0, // flags
CMSG_ENVELOPED, // message type
&EnvelopedEncodeInfo, // pointer to structure
szOID_RSA_signedData, // inner content OID
cbSignedBlob)) // size of content
{
printf("Length of the encoded BLOB will be %d.\n",cbEncodedBlob);
}
else
{
MyHandleError("Getting enveloped cbEncodedBlob length failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.
if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
printf("Memory has been allocated for the BLOB. \n");
}
else
{
MyHandleError("Enveloped malloc operation failed.");
}
//-------------------------------------------------------------------
// Open a message to encode.
if(hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_ENVELOPED, // message type
&EnvelopedEncodeInfo, // pointer to structure
szOID_RSA_signedData, // inner content OID
NULL)) // stream information (not used)
{
printf("The message to encode is open. \n");
}
else
{
MyHandleError("Enveloped OpenToEncode failed.");
}
//-------------------------------------------------------------------
// Update the message with the data.
if(CryptMsgUpdate(
hMsg, // handle to the message
pbSignedBlob, // pointer to the signed data BLOB
cbSignedBlob, // size of the data BLOB
TRUE)) // last call
{
printf("The signed BLOB has been added to the message. \n");
}
else
{
MyHandleError("Enveloped MsgUpdate failed.");
}
//-------------------------------------------------------------------
// Get the resulting message.
if(CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
pbEncodedBlob, // pointer to the enveloped,
// signed data BLOB
&cbEncodedBlob)) // size of the BLOB
{
printf("Enveloped message encoded successfully. \n");
}
else
{
MyHandleError("Enveloped MsgGetParam failed.");
}
//-------------------------------------------------------------------
// Clean up.
CertFreeCertificateContext(pRecipCert);
if(CertCloseStore(
hStoreHandle,
CERT_CLOSE_STORE_CHECK_FLAG))
{
printf("The certificate store closed without a certificate "
"left open. \n");
}
else
{
printf("The store closed but a certificate was still open. \n");
}
if(hMsg)
CryptMsgClose(hMsg);
if(hCryptProv)
CryptReleaseContext(hCryptProv,0);
} // end main
//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function to print an error message and exit
// the program.
// For most applications, replace this function with one
// that does more extensive error reporting.
void MyHandleError(char *s)
{
fprintf(stderr,"An error occurred in running the program. \n");
fprintf(stderr,"%s\n",s);
fprintf(stderr, "Error number %x.\n", GetLastError());
fprintf(stderr, "Program terminating. \n");
exit(1);
} // end MyHandleError
关于c - 使用 C 在 Windows 中使用 PFX/P12 证书签署字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59496196/
有人可以告诉我签署我的 clickonce 应用程序的步骤吗? 如果从某人那里购买证书,我该如何安装它在我的开发盒以及我希望它运行的服务器上? 请概述步骤。 马尔科姆 最佳答案 以下是我相信您正在执行
我正在使用命令行 jarsigner.exe -keystore Keys.jks base.apk debug0 使用我自己的 key 退出 APK ,在删除 META-INF/CERT.RSA、C
我使用 iTextSharp 签署 PDF 文件。但是 Adobe Reader 无法验证我的签名。我使用证书颁发机构生成的 SHA-2 测试证书(我也尝试过 SHA-1)。我已经为该机构的测试证
我在尝试签署 F# 类库项目时遇到了很多麻烦。 首先我试过这个thread ,使用 AssemblyKeyFileAttribute 但没有成功。 我还尝试将标志“--keyfile:keyfile.
我正在尝试掌握 .NET dll/程序集的正式签名。 尤其 何时以及如何使用私钥 创建/控制私钥的最佳实践 需要签署什么样的模块/最佳实践 最佳答案 请参阅使用 Strong Name Signatu
我有一个由五个项目组成的解决方案,每个项目都编译成单独的程序集。现在我正在对它们进行代码签名,但我很确定我做错了。这里的最佳做法是什么? 用不同的 key 对每个签名;确保密码不同 用不同的 key
我有一个由五个项目组成的解决方案,每个项目都编译为单独的程序集。现在我正在对它们进行代码签名,但我很确定我做错了。这里的最佳实践是什么? 使用不同的 key 对每个签名进行签名;确保密码不同 使用不同
尝试在 Java 中签署 SOAP 消息时抛出异常: 14:47:39.896 [AWT-EventQueue-0] ERROR com.ui.FinestraPrincipal - WSHandle
我正在运行 java web start 应用程序。由于应用程序数字签名已过期。我已经从 CA 购买了签名,并使用 storetype 作为 pkcs12 对我的 jar 文件进行了签名。 对 JNL
我已经在jar中手动添加了一些类文件。并在服务器中替换。但服务器没有拿出这个新的 jar 说:java.lang.SecurityException:类“test.TestProcess2”的签名者信
我想使用 keytool 对我的插件 jar 进行签名以生成 key 。 我知道有 -validity 选项,但如何设置它以使插件始终有效且永不过期。 谢谢 最佳答案 查看 keytool 文档: V
我有一个需要互联网访问的 Java 应用程序,因为它通过 WebView 嵌入了 Web 浏览器。 JavaFX 组件。 如果应用程序未打包在 Jar 中,则执行不会出现问题。但是,当打包在 Jar
我以前做过,但我完全忘记了如何签署 activeX 控件? 最佳答案 Digital Signing for ActiveX Components (MSDN) 关于activex - 签署 Acti
不知不觉中我删除了通常命名如下的钥匙串(keychain)系统证书 Software Signing com.apple.systemdefault com.apple.kerberos.kdc Ap
我尝试了一些基于 iText v1 或 v2 的数字 PDF 签名实用程序,发现似乎整个 PDF 都加载到内存中(对于 60M PDF 进程可能需要多达 300-400MB 的内存)。 最近的 iTe
我正在尝试使用 Python 对 Amazon 的 SimpleDB 服务进行 API 调用。例如,我使用的是最简单的请求 ListDomains。然而,无论我如何尝试,响应始终是“我们计算的请求签名
我的同事给了我一个Java项目来支持和增强。我需要签署 .jar 文件。我只找到了下一个文件:genkey.bat、project.cer、signjar.bat 和 keystore-jar.jar
目前我正在升级我的旧应用程序,它是使用 itextsharp 5.0.0 完成的到 5.4.5(最新)...但是我在获取等效代码时遇到了问题 PdfSignatureAppearance.SetCry
如果我有一个作为 API 请求发送的复杂对象(例如下面的订单),我应该在生成签名时包括所有属性还是应该只使用一个子集? 我问是因为我不清楚,而且从查看其他 API 的请求参数来看,请求参数是扁平和简单
为什么 WP7 项目不支持强名称签名?项目属性中没有签名选项卡。 无论如何,我已经使用 AssemblyInfo.cs 中的 AssemblyKeyFile 和 AssemblyDelaySign 属
我是一名优秀的程序员,十分优秀!