使用.pfx证书来包装,签署和创建PKCS#7 DER消息 [英] Enveloping, signing and creating PKCS#7 DER message with .pfx certificate
问题描述
我的任务是创建以 PKCS#7版本1.5(RFC 2315)DER(ITU-T建议X.690)
格式进行数字签名的数据 ANSI.1
与 X.509签名
?
My task is to create data that are digitally signed in format of PKCS#7 version 1.5 (RFC 2315) DER (ITU-T Recommendation X.690)
- basically ANSI.1
with X.509 signature
?
该邮件必须满足以下条件:
the message must satisfy following:
- 必须是
signedData
$ 必须包含签名数据必须包含签名数据必须包含签署人的证书 - 必须包含一个数字签名
- must be type
signedData
- must contain signed data
- must contain signer's certificate
- must contain one digital signature
我的代码如下
static void Main(string[] args)
{
string pfx = @"C:\Users\marek\Downloads\mfcr\marek-pfx.pfx";
string xml = @"C:\Users\marek\Downloads\mfcr\souhr20141.xml";
X509Certificate2 cert = new X509Certificate2(pfx, "thepass");
byte[] publicBytes = cert.RawData;
//var f = new FileStream(xml, System.IO.FileMode.Open);
var fileContent = System.IO.File.ReadAllBytes(xml);
char[] cArray = System.Text.Encoding.ASCII.GetString(fileContent).ToCharArray();
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] signedData = rsa.SignData(new System.Text.UTF8Encoding().GetBytes(cArray), new SHA1CryptoServiceProvider());
RSACryptoServiceProvider rsa2 = (RSACryptoServiceProvider)new X509Certificate2(publicBytes).PublicKey.Key;
var dataGenerator = new CmsEnvelopedDataStreamGenerator();
bool verified = rsa2.VerifyData(new System.Text.UTF8Encoding().GetBytes(cArray), new SHA1CryptoServiceProvider(), signedData);
File.WriteAllBytes(@"C:\Users\marek\Downloads\mfcr\Foo.p7b", signedData);
}
WebService
Iam发送 Foo.p7b
响应:文件不是预期的PKCS7(DER)格式。
The WebService
that Iam sending the Foo.p7b
responds with: File is not in expected format of PKCS7(DER).
代码发送 HttpWebRequest
:
static void Main(string[] args)
{
try
{
string fileName = (@"C:\Users\marek\Downloads\mfcr\Foo.p7b");
WebResponse rsp = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://adisepo.mfcr.cz/adistc/epo_podani");
request.ClientCertificates.Add(new X509Certificate(pfx,"thepass"));
request.Method = "POST";
request.ContentType = "application/pkcs7-signature";
request.Credentials = CredentialCache.DefaultNetworkCredentials;
var encoder = new UTF8Encoding();
var reqStream = request.GetRequestStream();
StreamWriter writer = new StreamWriter(request.GetRequestStream());
// Write the XML text into the stream
writer.WriteLine(GetTextFromXMLFile(fileName));
writer.Close();
reqStream.Close();
rsp = request.GetResponse();
StreamReader sr = new StreamReader(rsp.GetResponseStream());
string result = sr.ReadToEnd();
sr.Close();
Console.Write("\n příkaz odeslán \n");
Console.Write(result);
Console.ReadLine();
Console.Read();
}
catch (Exception ex)
{ Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
private static string GetTextFromXMLFile(string file)
{
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
return ret;
}
}
我遇到这个问题几乎5天 - 我肯定不是数字签名或证书方面的专家。
I'm struggling with this issue for almost 5 days - I'm surely not expert on digital signature or certificates.
从我到目前为止学到的东西 - 创建我应该这样的信息:
From what I learned so far - to create message like that I should do:
- 使用
私钥签署
/ li>xml
- 使用
公钥的blob信封
- Sign the
xml
with myprivate key
- Envelope that blob with my
public key
但是收件人如何检查我是否是真正的发件人?我应该用我的证书添加 HttpWebRequest
参数吗?或者第2步 - 包装邮件是否足以让他检查?
But how could the recipient check whether I am the real sender? Should I add to HttpWebRequest
parameter with my certificate? Or that step 2 - Enveloping the message is enough for him to check that?
感谢大家的时间和回复。
Thank you everyone for your time and replies.
推荐答案
您的代码尝试数字签名XML的字节表示,但签名XML需要在签名之前进行更多处理。例如,XML需要规范化(或者签名消息可以注入无符号数据),并且有一个用于包络签名的特殊格式。我不知道什么是Danovy Portal使用的实际方法,但如果它使用标准方式,您可以按照以下链接并签署您的数据。
Your code tries digitally sign byte representation of XML, but signing XML requires more processing before signing. For example XML requires to be canonicalized (or signed message can be injected with unsigned data), and there is a special format for enveloped signatures. I don't know what is actual method Danovy Portal uses, but if it uses standard way, you can follow the links below and sign your data.
只是为了获取信息(不要认为你真的需要阅读this)
W3C Xml签名规范
And just for information (don't think you really need to read this) W3C Xml Signature specification
EDIT:发送pkcs#7消息更改代码。生成
to send pkcs#7 message change the code. When generating
ContentInfo contentInfo = new ContentInfo(new System.Text.UTF8Encoding().GetBytes(cArray));
SignedCms cms = new SignedCms (contentInfo);
CmsSigner signer = new CmsSigner (cert);
cms.ComputeSignature (signer);
byte[] pkcs7=cms.Encode ();
File.WriteAllBytes(@"../../Foo.p7b", pkcs7);
发送时:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://adisepo.mfcr.cz/adistc/epo_podani");
//we don't need to add certificate to POST
// request.ClientCertificates.Add(new X509Certificate(pfx,"test"));
request.Method = "POST";
request.ContentType = "application/pkcs7-signature";
request.Credentials = CredentialCache.DefaultNetworkCredentials;
var encoder = new UTF8Encoding();
using (var reqStream = request.GetRequestStream())
{
// Write pkcs#7 into the stream
byte[] pkcs = File.ReadAllBytes(@"../../Foo.p7b");
reqStream.Write(pkcs, 0, pkcs.Length);
}
rsp = request.GetResponse();
这篇关于使用.pfx证书来包装,签署和创建PKCS#7 DER消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!