简体   繁体   English

通过使用 C# 传递整个 X509 证书链来签署 Soap header

[英]Signing Soap header by passing the whole X509 certificate chain using C#

All, I am trying to digitally sign a SOAP request header as part of calling a java api.全部,我正在尝试对 SOAP 请求 header 进行数字签名,作为调用 java Z8A5DA952ED12065E247D 的一部分I am using C# with.Net framework 4.5.我正在使用 C# 和 .Net 框架 4.5。 I manually created the soap request and when I send the signed request after signing with my X509Certificate's private key (.pfx cert file), the Mulesoft orchestration layer that Java service uses is complaining that my value doesn't contain the whole certificate chain.我手动创建了 soap 请求,当我在使用 X509Certificate 的私钥(.pfx 证书文件)签名后发送签名请求时,Java 服务使用的 Mulesoft 编排层抱怨我的值不包含整个证书链。 I use C#'s X509Certificate class's GetRawCertData() and converting this byte[] to base64 encoded string.我使用 C# 的 X509Certificate 类的 GetRawCertData() 并将这个 byte[] 转换为 base64 编码字符串。 I can see the intermediate and root certificate when I view this.pfx in my personal certificate store using mmc.当我使用 mmc 在我的个人证书存储中查看 this.pfx 时,我可以看到中间证书和根证书。 This.pfx certificate was given to me by our org's server admin. This.pfx 证书是由我们组织的服务器管理员提供给我的。 Does anyone know any other way to pass the whole certificate chain in the wsse:BinarySecurityToken element using C#?有谁知道使用 C# 在wsse:BinarySecurityToken元素中传递整个证书链的任何其他方式? Please see my sample soap envelope below.请在下面查看我的样本 soap 信封。

I am using HttpClient and Web Api (.Net framework) to send this request to Java service)我正在使用 HttpClient 和 Web Api(.Net 框架)将此请求发送到 Java 服务)

C# logic to set the value of the wsse:BinarySecurityToken element C# 逻辑设置 wsse:BinarySecurityToken 元素的值

X509Certificate2 x509Certificate = GetCertificateBySubjectName();
byte[] rawData = x509Certificate.GetRawCertData();    
var cerrtBase64String = Convert.ToBase64String(rawData);
binarySecurityToken.InnerText = cerrtBase64String ;

public  X509Certificate2 GetCertificateBySubjectName(string subjectName)
        {

            // Load the certificate from the certificate store.
            X509Certificate2 cert = null;

            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            try
            {
                // Open the store.
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

                // Find the certificate with the specified subject.
                cert = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false)[0];

                // Throw an exception of the certificate was not found.
                if (cert == null)
                {
                    throw new CryptographicException("The certificate could not be found.");
                }
            }

            catch (Exception ex)
            {
                var message = ex.Message;
            }
            finally
            {
                // Close the store even if an exception was thrown.
                store.Close();
            }

            return cert;
        }



<?xml version="1.0" encoding="UTF8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
 <wsse:Security xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
                xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" SOAP-ENV:mustUnderstand="1">
 <wsse:BinarySecurityToken  
               EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
               ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509" 
               wsu:Id="x509cert00">MIIChDCCAe2gAwIBAgIBADANBgkqhkiG9w0BAQUFADAwMQswCQYDVQQGEwJHQjEMMAoGA1UEChMD
                                   SUJNMRMwEQYDVQQDEwpXaWxsIFlhdGVzMB4XDTA2MDEzMTAwMDAwMFoXDTA3MDEzMTIzNTk1OVow
                                   MDELMAkGA1UEBhMCR0IxDDAKBgNVBAoTA0lCTTETMBEGA1UEAxMKV2lsbCBZYXRlczCBnzANBgkq
                                   hkiG9w0BAQEFAAOBjQAwgYkCgYEArsRj/n+3RN75+jaxuOMBWSHvZCB0egv8qu2UwLWEeiogePsR
                                   6Ku4SuHbBwJtWNr0xBTAAS9lEa70yhVdppxOnJBOCiERg7S0HUdP7a8JXPFzA+BqV63JqRgJyxN6
                                   msfTAvEMR07LIXmZAte62nwcFrvCKNPCFIJ5mkaJ9v1p7jkCAwEAAaOBrTCBqjA/BglghkgBhvhC
                                   AQ0EMhMwR2VuZXJhdGVkIGJ5IHRoZSBTZWN1cml0eSBTZXJ2ZXIgZm9yIHovT1MgKFJBQ0YpMDgG
                                   ZQVRFU0BVSy5JQk0uQ09ggdJQk0uQ09NhgtXV1cuSUJNLkNPTYcECRRlBjAO
 </wsse:BinarySecurityToken>
 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                 xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
                 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
                 xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
   <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <c14n:InclusiveNamespaces xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds wsu xenc SOAP-ENV "/>
   </ds:CanonicalizationMethod>
   <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
   <ds:Reference URI="#TheBody">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
       <c14n:InclusiveNamespaces xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsu SOAP-ENV "/>
     </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
    <ds:DigestValue>QORZEA+gpafluShspHxhrjaFlXE=</ds:DigestValue> 
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>drDH0XESiyN6YJm27mfK1ZMG4Q4IsZqQ9N9V6kEnw2lk7aM3if77XNFnyKS4deglbC3ga11kkaFJ
                     p4jLOmYRqqycDPpqPm+UEu7mzfHRQGe7H0EnFqZpikNqZK5FF6fvYlv2JgTDPwrOSYXmhzwegUDT
                     lTVjOvuUgXYrFyaO3pw=</ds:SignatureValue>
   <ds:KeyInfo>
    <wsse:SecurityTokenReference>
      <wsse:Reference URI="#x509cert00" 
                      ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509"/>
    </wsse:SecurityTokenReference>
   </ds:KeyInfo>
  </ds:Signature>
 </wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TheBody">
 <getVersion xmlns="http://msgsec.wssecfvt.ws.ibm.com"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

GetRawCertData() returns the bytes that make up the certificate, ignoring any "attached data" like the private key or friendly name or whatnot. GetRawCertData()返回构成证书的字节,忽略任何“附加数据”,如私钥或友好名称等。 It's not a tie-back to the file that it was loaded from or anything magical.它不是与加载它的文件或任何神奇的文件的绑定。

the whole certificate chain整个证书链

You don't show how you loaded the PFX, but the most common way is the X509Certificate2 constructor ( new X509Certificate2(pfx, pwd, maybeSomeFlags) ).您没有显示如何加载 PFX,但最常见的方式是 X509Certificate2 构造函数( new X509Certificate2(pfx, pwd, maybeSomeFlags) )。 Since that's a single certificate's constructor it can only load one certificate.由于这是一个证书的构造函数,它只能加载一个证书。 The other way is to import it into a collection另一种方法是将其导入集合

X509Certificate2Collection coll = new X509Certificate2Collection();
coll.Import(pfx, pwd, maybeSomeFlags);

from there you'd presumably loop whatever you did to add x509cert00 for all the elements in that collection.从那里你可能会循环你为该集合中的所有元素添加x509cert00所做的任何事情。 Of course, that's assuming that the collection is sorted the way you like and has no extraneous data.当然,这是假设集合按照您喜欢的方式排序并且没有多余的数据。 If you want to know that it's sorted into a proper chain you'd have to run the signing certificate through X509Chain.Build (after copying the rest of the collection into chain.ChainPolicy.ExtraStore ).如果您想知道它已分类到正确的链中,则必须通过X509Chain.Build运行签名证书(在将集合的 rest 复制到chain.ChainPolicy.ExtraStore )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM