如何在 C# 中复制 CAPICOM SignedData.Sign() 方法
How to replicate CAPICOM SignedData.Sign() method in C#
我需要为使用 VB6/CAPICOM 组件的现有经典 Asp 网站编写测试工具。目的是重新创建 SignedData.Sign() 的结果,这样我就可以 POST 将其发送到经典 Asp 网站,在那里它将使用 CAPICOM 解码有效负载。
VB6 CAPICOM 供参考
Function SignContent(ByVal strXmlToSign As String) As String
Dim strSignedString As String
Dim objSign As SignedData ‘ From CAPICOM library
Set objSign = New SignedData
objSign.Content = strXmlToSign
strSignedString = objSign.Sign
Set objSign = Nothing
SignContent = strSignedString
End Function
我一直在使用 CAPICOM 文档 here 作为指南
等效于 C#
public string Sign(string dataToSign)
{
ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(dataToSign));
// Create a new, nondetached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo);
// get cert from store by Serial Number
X509Certificate2 cert = GetCertificateBy("my-cert-serial-number");
CmsSigner signer = new CmsSigner(cert);
// Sign the message.
signedCms.ComputeSignature(signer);
// Encode the message.
var encoded = signedCms.Encode();
// mimic default EncodingType; CAPICOM_ENCODE_BASE64 Data is saved as a base64 - encoded string.
return Convert.ToBase64String(encoded);
}
目前C#生成的签名无法被CAPICOM组件解码。
经过大量侦探工作后,我设法将一条消息发送到可以解码 CAPICOM 组件的端点。工作解决方案如下:
public string Sign(string dataToSign)
{
// Default to SHA1; required if targeting .Net Framework 4.7.1 or above
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
// The dataToSign byte array holds the data to be signed.
ContentInfo contentInfo = new ContentInfo(Encoding.Unicode.GetBytes(dataToSign));
// Create a new, nondetached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo, false);
X509Certificate2 cert = GetCertificate();
CmsSigner signer = new CmsSigner(cert);
// Sign the message.
signedCms.ComputeSignature(signer);
// Encode the message.
var encoded = signedCms.Encode();
// mimic default EncodingType; CAPICOM_ENCODE_BASE64 Data is saved as a base64 - encoded string.
return Convert.ToBase64String(encoded, Base64FormattingOptions.InsertLineBreaks);
}
更改摘要:
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
如果以 .NET Framework 4.7.1+ 为目标(我的应用以 .NET 4.7.1 为目标),这些操作默认启用 SHA256。此更改是必要的,因为 SHA1 不再被认为是安全的。 Source
ContentInfo contentInfo = new ContentInfo(Encoding.Unicode.GetBytes(dataToSign));
已从编码 UTF8 更改为 Unicode。
return Convert.ToBase64String(encoded, Base64FormattingOptions.InsertLineBreaks);
使用换行符选项匹配 Capicom 输出。
我需要为使用 VB6/CAPICOM 组件的现有经典 Asp 网站编写测试工具。目的是重新创建 SignedData.Sign() 的结果,这样我就可以 POST 将其发送到经典 Asp 网站,在那里它将使用 CAPICOM 解码有效负载。
VB6 CAPICOM 供参考
Function SignContent(ByVal strXmlToSign As String) As String
Dim strSignedString As String
Dim objSign As SignedData ‘ From CAPICOM library
Set objSign = New SignedData
objSign.Content = strXmlToSign
strSignedString = objSign.Sign
Set objSign = Nothing
SignContent = strSignedString
End Function
我一直在使用 CAPICOM 文档 here 作为指南
等效于 C#
public string Sign(string dataToSign)
{
ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(dataToSign));
// Create a new, nondetached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo);
// get cert from store by Serial Number
X509Certificate2 cert = GetCertificateBy("my-cert-serial-number");
CmsSigner signer = new CmsSigner(cert);
// Sign the message.
signedCms.ComputeSignature(signer);
// Encode the message.
var encoded = signedCms.Encode();
// mimic default EncodingType; CAPICOM_ENCODE_BASE64 Data is saved as a base64 - encoded string.
return Convert.ToBase64String(encoded);
}
目前C#生成的签名无法被CAPICOM组件解码。
经过大量侦探工作后,我设法将一条消息发送到可以解码 CAPICOM 组件的端点。工作解决方案如下:
public string Sign(string dataToSign)
{
// Default to SHA1; required if targeting .Net Framework 4.7.1 or above
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
// The dataToSign byte array holds the data to be signed.
ContentInfo contentInfo = new ContentInfo(Encoding.Unicode.GetBytes(dataToSign));
// Create a new, nondetached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo, false);
X509Certificate2 cert = GetCertificate();
CmsSigner signer = new CmsSigner(cert);
// Sign the message.
signedCms.ComputeSignature(signer);
// Encode the message.
var encoded = signedCms.Encode();
// mimic default EncodingType; CAPICOM_ENCODE_BASE64 Data is saved as a base64 - encoded string.
return Convert.ToBase64String(encoded, Base64FormattingOptions.InsertLineBreaks);
}
更改摘要:
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
如果以 .NET Framework 4.7.1+ 为目标(我的应用以 .NET 4.7.1 为目标),这些操作默认启用 SHA256。此更改是必要的,因为 SHA1 不再被认为是安全的。 Source
ContentInfo contentInfo = new ContentInfo(Encoding.Unicode.GetBytes(dataToSign));
已从编码 UTF8 更改为 Unicode。
return Convert.ToBase64String(encoded, Base64FormattingOptions.InsertLineBreaks);
使用换行符选项匹配 Capicom 输出。