使用.pfx证书来包装,签署和创建PKCS#7 DER消息 [英] Enveloping, signing and creating PKCS#7 DER message with .pfx certificate

查看:663
本文介绍了使用.pfx证书来包装,签署和创建PKCS#7 DER消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是创建以 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:


  1. 使用私钥签署 xml / li>
  2. 使用公钥的blob信封

  1. Sign the xml with my private key
  2. 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.

MSDN :如何:使用数字签名签署XML文档

如何包封签名看起来

只是为了获取信息(不要认为你真的需要阅读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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆