文章 姚 鑫 · 九月 30, 2024 2m read

第三十六章 结合加密和签名 - 使用对称密钥签名并加密

使用对称密钥签名并加密

签名然后加密(使用对称密钥时):

  1. 按照使用<DerivedKeyToken> 进行加密中的步骤进行操作。
  2. 按照使用<DerivedKeyToken> 进行签名中的步骤进行操作。

使用<DerivedKeyToken>元素

以下示例使用对称密钥进行签名和加密。它使用消息接收者的公钥创建一个 <EncryptedKey>元素,然后使用该元素生成两个 <DerivedKeyToken> 元素,一个用于签名,一个用于加密:

 // create UsernameToken
  set userToken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")

  //get credentials of message recipient
  set x509alias = "servernopassword"
  set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias) 

  //get EncryptedKey element
  set enc=##class(%XML.Security.EncryptedKey).CreateX509(cred,$$$SOAPWSEncryptNone)
  do client.SecurityOut.AddSecurityElement(enc)

  // get derived keys
  set dkenc=##class(%SOAP.WSSC.DerivedKeyToken).Create(enc,$$$SOAPWSReferenceEncryptedKey)
  do client.SecurityOut.AddSecurityElement(dkenc)
  set dksig=##class(%SOAP.WSSC.DerivedKeyToken).Create(enc,$$$SOAPWSReferenceEncryptedKey)
  do client.SecurityOut.AddSecurityElement(dksig)

  // create and add signature
  set sig=##class(%XML.Security.Signature).Create(dksig,,$$$SOAPWSReferenceDerivedKey)
  do client.SecurityOut.AddSecurityElement(sig) 
 
  // ReferenceList to encrypt Body and Username. Add after signing
  set reflist=##class(%XML.Security.ReferenceList).%New()
  set refopt=$$$SOAPWSReferenceDerivedKey
  set encryptedData=##class(%XML.Security.EncryptedData).Create(dkenc,userToken,refopt)
  set dataref=##class(%XML.Security.DataReference).Create(encryptedData)
  do reflist.AddReference(dataref)
  set encryptedData=##class(%XML.Security.EncryptedData).Create(dkenc,"",refopt)
  set dataref=##class(%XML.Security.DataReference).Create(encryptedData)
  do reflist.AddReference(dataref)
  do client.SecurityOut.AddSecurityElement(reflist)
  
  // Add UsernameToken; force after ReferenceList so that it can decrypt properly
  do client.SecurityOut.AddSecurityElement(userToken,reflist)

该客户端发送如下消息:

<SOAP-ENV:Envelope [parts omitted]'>  
   <SOAP-ENV:Header>
      <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#" 
                       Id="Id-A0CBB4B7-18A8-40C1-A2CD-C0C383BF9531">
            <EncryptionMethod Algorithm="[parts omitted]#rsa-oaep-mgf1p">
               <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 
                             Algorithm="[parts omitted]#sha1"></DigestMethod>
            </EncryptionMethod>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
               <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                  <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                                 ValueType="[parts omitted]#ThumbprintSHA1">
              5afOHv1w7WSXwDyz6F3WdM1r6cM=</KeyIdentifier>
               </SecurityTokenReference>
            </KeyInfo>
            <CipherData>
               <CipherValue>fR4hoJy4[parts omitted]Gmq1xg==</CipherValue>
            </CipherData>
         </EncryptedKey>
         <DerivedKeyToken xmlns="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" 
                          xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" 
                          wsu:Id="Enc-43F73EB2-77EC-4D72-9DAD-17B1781BC49C">
            <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
               <Reference URI="#Id-A0CBB4B7-18A8-40C1-A2CD-C0C383BF9531"></Reference>
            </SecurityTokenReference>
            <Nonce>Q1wDt0PSSLmARcy+Pg49Sg==</Nonce>
         </DerivedKeyToken>
         <DerivedKeyToken xmlns="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" 
                          xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" 
                          wsu:Id="Enc-ADE64310-E695-4630-9DA6-A818EF5CEE9D">
            <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
               <Reference URI="#Id-A0CBB4B7-18A8-40C1-A2CD-C0C383BF9531"></Reference>
            </SecurityTokenReference>
            <Offset>0</Offset>
            <Length>24</Length>
            <Nonce>PvaakhgdxoBVLR6I1j6KGA==</Nonce>
         </DerivedKeyToken>
         <ReferenceList xmlns="http://www.w3.org/2001/04/xmlenc#">
            <DataReference URI="#Enc-F8013636-5339-4C25-87CD-C241330865F5"></DataReference>
            <DataReference URI="#Enc-CDF877AC-8347-4903-97D9-E8238C473DC4"></DataReference>
         </ReferenceList>
         <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                        Id="Enc-F8013636-5339-4C25-87CD-C241330865F5" 
                        Type="http://www.w3.org/2001/04/xmlenc#Element">
            <EncryptionMethod Algorithm="[parts omitted]#aes256-cbc"></EncryptionMethod>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
               <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                  <Reference URI="#Enc-43F73EB2-77EC-4D72-9DAD-17B1781BC49C"></Reference>
               </SecurityTokenReference>
            </KeyInfo>
            <CipherData>
               <CipherValue>ebxkmD[parts omitted]ijtJg==</CipherValue>
            </CipherData>
         </EncryptedData>
         <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
               <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
               </CanonicalizationMethod>
               <SignatureMethod Algorithm="[parts omitted]#hmac-sha1"></SignatureMethod>
               <Reference URI="#Body-C0D7FF05-EE59-41F6-939D-7B2F2B883E5F">
                  <Transforms>
                     <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
                  </Transforms>
                  <DigestMethod Algorithm="[parts omitted]#sha1"></DigestMethod>
                  <DigestValue>vic7p2selz4Wvm1nAX67p0xF1VI=</DigestValue>
               </Reference>
            </SignedInfo>
            <SignatureValue>TxIBa4a8wX5oFN+eyjjsUuLdn7U=</SignatureValue>
            <KeyInfo>
               <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                  <Reference URI="#Enc-ADE64310-E695-4630-9DA6-A818EF5CEE9D"></Reference>
               </SecurityTokenReference>
            </KeyInfo>
         </Signature>
      </Security>  
   </SOAP-ENV:Header>  
   <SOAP-ENV:Body wsu:Id="Body-C0D7FF05-EE59-41F6-939D-7B2F2B883E5F">
      <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                     Id="Enc-CDF877AC-8347-4903-97D9-E8238C473DC4" 
                     Type="http://www.w3.org/2001/04/xmlenc#Content">
         <EncryptionMethod Algorithm="[parts omitted]#aes256-cbc"></EncryptionMethod>
         <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
               <Reference URI="#Enc-43F73EB2-77EC-4D72-9DAD-17B1781BC49C"></Reference>
            </SecurityTokenReference>
         </KeyInfo>
         <CipherData>
            <CipherValue>vYtzDsv[parts omitted]GohGsL6</CipherValue>
         </CipherData>
      </EncryptedData>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

使用对称密钥加密并签名

加密然后签名(使用对称密钥时):

  1. 按照使用<DerivedKeyToken>进行签名中的步骤进行操作。
  2. 按照使用<DerivedKeyToken>进行加密中的步骤进行操作。

安全标头元素的顺序

一般情况下,应该按照执行处理的顺序将安全元素添加到安全标头中。消息接收者应该能够从头到尾处理该消息,而无需任何前向引用。

下表列出了使用非对称密钥时安全标头元素的最终顺序(这些场景使用非对称密钥绑定):

签名然后加密签名然后加密
Other header elements
<EncryptedKey>
<Signature>
Other header elements
<EncryptedKey>
<Signature>
<ReferenceList>

下表列出了使用对称密钥时安全标头元素的结果顺序(这些场景使用对称密钥绑定):

签名然后加密签名然后加密
Other header elements
<EncryptedKey>
<DerivedKeyToken>
<DerivedKeyToken>
<ReferenceList>
<Signature>
Other header elements
<EncryptedKey>
<DerivedKeyToken>
<DerivedKeyToken>
<Signature>
<ReferenceList>
0
0 78
文章 姚 鑫 · 九月 29, 2024 3m read

第三十五章 结合加密和签名

可以在同一条消息中加密和签名。在大多数情况下,只需组合前面主题中给出的方法即可。本主题讨论了多种场景。

使用非对称密钥签名并加密

要签名然后加密(使用非对称密钥时),请执行以下操作:

  1. 按照添加数字签名中的步骤进行操作。
  2. 按照加密安全标头元素中的步骤进行操作。

或者按照加密 SOAP 主体中的步骤进行操作。

使用非对称密钥加密并签名

要仅加密 SOAP 主体,然后添加数字签名(使用非对称密钥时),请执行以下操作:

  1. 按照加密 SOAP 主体中的步骤进行操作。
  2. 按照添加数字签名中的步骤进行操作。

要加密任何安全标头元素,然后添加数字签名(使用非对称密钥时),必须使用顶级 <ReferenceList> 元素(在文档的其他地方不需要)。在这种情况下,请执行以下操作:

  1. 按照加密安全标头元素中的步骤 1 — 4 进行操作。
  2. 对于要加密的每个安全标头元素,根据该元素创建一个 <EncryptedData> 元素。为此,请调用 %XML.Security.EncryptedDataCreate() 类方法。在此过程中,指定所有三个参数:

a. 在前面的步骤中创建的加密密钥实例。

b. 要加密的安全标头元素。

c. $$$SOAPWSReferenceEncryptedKey,指定 <EncryptedData> 如何使用加密密钥实例。

 set refopt=$$$SOAPWSReferenceEncryptedKey
 set encdata=##class(%XML.Security.EncryptedData).Create(enckey,userToken,refopt)
  1. 创建 <ReferenceList> 元素。为此调用 %XML.Security.ReferenceList%New() 方法。例如:
  2. 在此 <ReferenceList> 中,创建一个指向 <EncryptedData> 元素的Reference>。为此,请对每个 <EncryptedData> 执行以下操作:

a. 调用 %XML.Security.DataReferenceCreate() 类方法,并指定加密数据实例作为参数。此方法返回 %XML.Security.DataReference的实例。

b. 调用引用列表实例的 AddReference() 方法并指定数据引用实例作为参数。

 set dataref=##class(%XML.Security.DataReference).Create(encdata)
 do reflist.AddReference(dataref)
  1. <ReferenceList> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,请指定您的引用列表实例。例如:
 do ..SecurityOut.AddSecurityElement(reflist)

注意:在添加其他项目之前,必须先添加 <ReferenceList> 元素。

  1. <EncryptedKey> 元素添加到 WS-Security 标头元素。使用 AddSecurityElement()。例如:
 do ..SecurityOut.AddSecurityElement(enckey)
  1. 将加密的安全标头元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。在本例中,指定两个参数:

a. 要包含的安全标头元素(而不是基于该元素的 %XML.Security.EncryptedData的实例)。

b. 加密密钥实例。第二个参数指定第一个参数指定的项的放置位置。如果参数为 AB,则 IRIS 确保 AB 之后。指定此项以便收件人首先处理加密密钥,然后再处理依赖于它的加密安全标头元素。

 do ..SecurityOut.AddSecurityElement(userToken,enckey)

或者,如果加密的安全标头元素是<Signature>,,则使用 AddSecurityElement()

  1. 按照步骤添加数字签名。
  2. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。
0
0 82
文章 姚 鑫 · 九月 26, 2024 2m read

第三十四章 使用派生密钥令牌进行加密和签名 - 使用 <DerivedKeyToken> 进行签名

要使用 <DerivedKeyToken>进行签名,请使用以下步骤:

  1. 如果想要签署任何安全标头元素,请创建这些安全标头元素。
  2. 创建 <DerivedKeyToken> 并将其添加到 WS-Security 标头,如创建和添加 <DerivedKeyToken> 中所述。

请注意,此步骤还会创建并添加 <DerivedKeyToken> 所基于的 <EncryptedKey> 元素。

  1. 根据派生的密钥令牌创建<Signature> 元素。为此,请调用 %XML.Security.SignatureCreate() 类方法。例如:
 set dsig=##class(%XML.Security.Signature).Create(dkt)

此方法返回 %XML.Security.Signature 的实例,该实例表示 <Signature> 标头元素。签名值通过 HMAC-SHA1 摘要算法计算,使用 <DerivedKeyToken> 隐含的对称密钥。

<Signature> 元素适用于消息的一组默认部分;可以指定一组不同的部分。

  1. 将数字签名添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于参数,请指定上一步中创建的签名对象。例如:
 do ..SecurityOut.AddSecurityElement(dsig)

例如,以下客户端代码对 SOAP 主体进行签名:

 // get credentials
 set cred = ##class(%SYS.X509Credentials).GetByAlias("servercred") 

 // get EncryptedKey element that does not encrypt the body
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(cred,$$$SOAPWSEncryptNone)
 //add to WS-Security Header
 do client.SecurityOut.AddSecurityElement(enckey)

 // get derived key & add to header
 set dksig=##class(%SOAP.WSSC.DerivedKeyToken).Create(enckey,$$$SOAPWSReferenceEncryptedKey)
 //add to WS-Security Header
 do client.SecurityOut.AddSecurityElement(dksig)

 // create a signature and add it to the security header 
 set sig=##class(%XML.Security.Signature).Create(dksig,,$$$SOAPWSReferenceDerivedKey)
 do client.SecurityOut.AddSecurityElement(sig)

客户端发送如下消息:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope [parts omitted]>
  <SOAP-ENV:Header>
    <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#" 
                   Id="Id-6188CA15-22BF-41EB-98B1-C86D4B242C9F">
        <EncryptionMethod Algorithm="[parts omitted]#rsa-oaep-mgf1p">
          <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 
              Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
        </EncryptionMethod>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <SecurityTokenReference 
                xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                           ValueType="[parts omitted]#ThumbprintSHA1">5afOHv1w7WSXwDyz6F3WdM1r6cM=
            </KeyIdentifier>
          </SecurityTokenReference>
        </KeyInfo>
        <CipherData>
          <CipherValue>VKyyi[parts omitted]gMVfayVYxA==</CipherValue>
          </CipherData>
      </EncryptedKey>
      <DerivedKeyToken xmlns="[parts omitted]ws-secureconversation/200512" 
                       xmlns:wsc=[parts omitted]ws-secureconversation/200512" 
                       wsu:Id="Enc-BACCE807-DB34-46AB-A9B8-42D05D0D1FFD">
        <SecurityTokenReference 
             xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <Reference URI="#Id-6188CA15-22BF-41EB-98B1-C86D4B242C9F"></Reference>
        </SecurityTokenReference>
        <Offset>0</Offset>
        <Length>24</Length>
        <Nonce>IgSfZJ1jje710zadbPXf1Q==</Nonce>
      </DerivedKeyToken>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
          </CanonicalizationMethod>
          <SignatureMethod Algorithm="[parts omitted]#hmac-sha1"></SignatureMethod>
          <Reference URI="#Body-B08978B3-8BE8-4365-A352-1934D7C33D2D">
             <Transforms>
               <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
             </Transforms>
             <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
             <DigestValue>56gxpK1mSVW7DN5LUYRvqDbMt0s=</DigestValue>
           </Reference>
        </SignedInfo>
        <SignatureValue>aY4dKX17zDS2SF+BXlVTHcEituc=</SignatureValue>
        <KeyInfo>
          <SecurityTokenReference 
                xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
              <Reference URI="#Enc-BACCE807-DB34-46AB-A9B8-42D05D0D1FFD"></Reference>
          </SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </Security>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body wsu:Id="Body-B08978B3-8BE8-4365-A352-1934D7C33D2D">
    [omitted]
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

0
0 77
文章 姚 鑫 · 九月 25, 2024 1m read

第三十三章 使用派生密钥令牌进行加密和签名 - 使用 <DerivedKeyToken>

进行加密(一)

  1. 如果加密了任何安全标头元素,请将它们添加到 WS-Security 标头元素中。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。在这种情况下,需要两个参数:

a. 安全标头元素(而不是从中生成的的 %XML.Security.EncryptedData)。

b. 引用列表实例。第二个参数指定将第一个参数指定的项目放在何处。如果参数是 AB,则 IRIS 确保 AB 之后。指定此项以便收件人首先处理引用列表,然后再处理依赖于它的加密安全标头元素。

 do client.SecurityOut.AddSecurityElement(userToken,reflist)

如果仅加密了 SOAP 主体,系统会自动将 <EncryptedData> 元素作为 <Body>的子元素。

  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。

例如,以下客户端代码对 SOAP 主体和 <UsernameToken>进行加密:

  // Create UsernameToken
  set userToken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
 
  // get credentials for encryption
  set cred = ##class(%SYS.X509Credentials).GetByAlias("servercred") 

  // get EncryptedKey element to encrypt <UsernameToken)
  // $$$SOAPWSEncryptNone means that this key does not encrypt the body
  set enckey=##class(%XML.Security.EncryptedKey).CreateX509(cred,$$$SOAPWSEncryptNone)
  //add to WS-Security Header
  do client.SecurityOut.AddSecurityElement(enckey)

  // get derived key to use for encryption
  // second argument specifies how the derived key 
  // refers to the key on which it is based
  set dkenc=##class(%SOAP.WSSC.DerivedKeyToken).Create(enckey,
     $$$SOAPWSReferenceEncryptedKey)
  //add to WS-Security Header
  do client.SecurityOut.AddSecurityElement(dkenc)
  
  // create <EncryptedData> element to contain <UserToken>
  set encdata=##class(%XML.Security.EncryptedData).Create(dkenc,userToken,
     $$$SOAPWSReferenceDerivedKey)
  
  // create <EncryptedData> element to contain SOAP body
  set encdata2=##class(%XML.Security.EncryptedData).Create(dkenc,"",
     $$$SOAPWSReferenceDerivedKey)

  // create <ReferenceList> with <DataReference> elements that
  // point to these two <EncryptedData> elements
  set reflist=##class(%XML.Security.ReferenceList).%New()
  set dataref=##class(%XML.Security.DataReference).Create(encdata)
  do reflist.AddReference(dataref)
  set dataref2=##class(%XML.Security.DataReference).Create(encdata2)
  do reflist.AddReference(dataref2)

  // add <ReferenceList> to WS-Security header
  do client.SecurityOut.AddSecurityElement(reflist)
  // add encrypted <UserName> to security header;
  // 2nd argument specifies position
  do client.SecurityOut.AddSecurityElement(userToken,reflist)

  // encrypted SOAP body is handled automatically

客户端发送如下消息:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope [parts omitted]>
  <SOAP-ENV:Header>
    <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#" 
                  Id="Id-658202BF-239A-4A8C-A100-BB25579F366B">
        <EncryptionMethod Algorithm="[parts omitted]#rsa-oaep-mgf1p">
          <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 
                       Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
          </DigestMethod>
        </EncryptionMethod>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                           ValueType="[parts omitted]#ThumbprintSHA1">5afOHv1w7WSXwDyz6F3WdM1r6cM=
            </KeyIdentifier>
          </SecurityTokenReference>
        </KeyInfo>
        <CipherData>
          <CipherValue>tFeKrZKw[parts omitted]r+bx7KQ==</CipherValue>
        </CipherData>
      </EncryptedKey>
      <DerivedKeyToken xmlns="[parts omitted]ws-secureconversation/200512" 
                    xmlns:wsc="[parts omitted]ws-secureconversation/200512" 
                    wsu:Id="Enc-943C6673-E3F3-48E4-AA24-A7F82CCF6511">
        <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <Reference URI="#Id-658202BF-239A-4A8C-A100-BB25579F366B"></Reference>
        </SecurityTokenReference>
        <Nonce>GbjRvVNrPtHs0zo/w9Ne0w==</Nonce>
      </DerivedKeyToken>
      <ReferenceList xmlns="http://www.w3.org/2001/04/xmlenc#">
        <DataReference URI="#Enc-358FB189-81B3-465D-AFEC-BC28A92B179C"></DataReference>
        <DataReference URI="#Enc-9EF5CCE4-CF43-407F-921D-931B5159672D"></DataReference>
      </ReferenceList>
      <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                  Id="Enc-358FB189-81B3-465D-AFEC-BC28A92B179C" 
                  Type="http://www.w3.org/2001/04/xmlenc#Element">
        <EncryptionMethod Algorithm="[parts omitted]#aes256-cbc"></EncryptionMethod>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
           <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <Reference URI="#Enc-943C6673-E3F3-48E4-AA24-A7F82CCF6511"></Reference>
           </SecurityTokenReference>
        </KeyInfo>
        <CipherData>
          <CipherValue>e4//6aWGqo1dIQ7ZAF[parts omitted]KZcj99N78A==</CipherValue>
        </CipherData>
      </EncryptedData>
    </Security>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                   Id="Enc-9EF5CCE4-CF43-407F-921D-931B5159672D" 
                   Type="http://www.w3.org/2001/04/xmlenc#Content">
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc">
        </EncryptionMethod>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <Reference URI="#Enc-943C6673-E3F3-48E4-AA24-A7F82CCF6511"></Reference>
          </SecurityTokenReference>
        </KeyInfo>
        <CipherData>
          <CipherValue>Q3XxuNjSan[parts omitted]x9AD7brM4</CipherValue>
        </CipherData>
    </EncryptedData>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

再举一个例子,以下 Web 服务在入站消息中接收 <EncryptedKey> ,并使用它来生成 <DerivedKeyToken> ,用于加密响应的各个部分:

  // create <DerivedKeyToken> based on first <EncryptedKey> in inbound message;
  // refer to it with SHA1 thumbprint
  set refopt=$$$SOAPWSReferenceEncryptedKeySHA1
  set dkenc=##class(%SOAP.WSSC.DerivedKeyToken).Create(,refopt)
  do ..SecurityOut.AddSecurityElement(dkenc)
  
  // create <EncryptedData> element to contain SOAP body
  set encdata=##class(%XML.Security.EncryptedData).Create(dkenc,"",
     $$$SOAPWSReferenceDerivedKey)
  
  // create <ReferenceList> with <DataReference> elements that
  // point to the <EncryptedData> elements
  set reflist=##class(%XML.Security.ReferenceList).%New()
  set dataref=##class(%XML.Security.DataReference).Create(encdata)
  do reflist.AddReference(dataref)

  // add <ReferenceList> to WS-Security header
  do ..SecurityOut.AddSecurityElement(reflist)

Web 服务发送如下消息:

<SOAP-ENV:Envelope [parts omitted]>  
   <SOAP-ENV:Header>
      <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <DerivedKeyToken xmlns="[parts omitted]ws-secureconversation/200512" 
                          xmlns:wsc="[parts omitted]ws-secureconversation/200512" 
                          wsu:Id="Enc-D69085A9-9608-472D-85F3-44031586AB35">
            <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd" 
                               s01:TokenType="[parts omitted]#EncryptedKey" 
                               xmlns:s01="h[parts omitted]oasis-wss-wssecurity-secext-1.1.xsd">
               <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                              [parts omitted]#EncryptedKeySHA1">
                     U8CEWXdUPsIk/r8JT+2KdwU/gSw=
               </KeyIdentifier>
            </SecurityTokenReference>
            <Nonce>nJWyIJUcXXLd4k1tbNg10w==</Nonce>
         </DerivedKeyToken>
         <ReferenceList xmlns="http://www.w3.org/2001/04/xmlenc#">
            <DataReference URI="#Enc-0FF09175-B594-4198-9850-57D40EB66DC3"></DataReference>
         </ReferenceList>
      </Security>  
   </SOAP-ENV:Header>  
   <SOAP-ENV:Body>
      <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                     Id="Enc-0FF09175-B594-4198-9850-57D40EB66DC3" 
                     Type="http://www.w3.org/2001/04/xmlenc#Content">
         <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc">
         </EncryptionMethod>
         <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SecurityTokenReference xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
               <Reference URI="#Enc-D69085A9-9608-472D-85F3-44031586AB35"></Reference>
            </SecurityTokenReference>
         </KeyInfo>
         <CipherData>
            <CipherValue>NzI94WnuQU4uBO[parts omitted]xHZpJSA==</CipherValue>
         </CipherData>
      </EncryptedData>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
0
0 43
文章 姚 鑫 · 九月 24, 2024 2m read

第三十二章 使用派生密钥令牌进行加密和签名 - 使用 <DerivedKeyToken>

进行加密

要使用 <DerivedKeyToken> 进行加密,请使用以下步骤:

  1. 如果要加密一个或多个安全标头元素,请创建这些安全标头元素。.
  2. 创建 <DerivedKeyToken> 并将其添加到 WS-Security 标头,如创建和添加 <DerivedKeyToken> 中所述。

请注意,此步骤还会创建并添加 <EncryptedKey> 所基于的 <EncryptedKey> 元素。

  1. 对于要加密的每个元素,请根据该元素创建一个 <EncryptedData> 元素。为此,请调用 %XML.Security.EncryptedDataCreate() 类方法。在此过程中,请指定以下参数:

a. 派生密钥令牌 b. 要加密的项目。省略此参数可加密正文。 c. 指定 <EncryptedData> 元素如何引用 <DerivedKeyToken> 的宏。在此场景中,当前唯一支持的值是 $$$SOAPWSReferenceDerivedKey

例如,加密 <UsernameToken>

 set refopt=$$$SOAPWSReferenceDerivedKey
 set encryptedData=##class(%XML.Security.EncryptedData).Create(dkenc,userToken,refopt) 

或者,加密正文:

 set refopt=$$$SOAPWSReferenceDerivedKey
 set encryptedData=##class(%XML.Security.EncryptedData).Create(dkenc,,refopt) 
  1. 创建 <ReferenceList> 元素。为此,在类中调用 %XML.Security.ReferenceList%New() 方法。例如:
 set reflist=##class(%XML.Security.ReferenceList).%New() 
  1. 在这个<ReferenceList>中,创建一个指向<EncryptedData>元素的<ReferenceList>。为此,对每个<EncryptedData>执行以下操作:

a. 调用 %XML.Security.DataReferenceCreate() 类方法,并指定加密数据实例作为参数。此方法返回 %XML.Security.DataReference的实例。

b. 调用引用列表实例的 AddReference() 方法并指定数据引用实例作为参数。

 set dataref=##class(%XML.Security.DataReference).Create(encdata)
 do reflist.AddReference(dataref)
 set dataref2=##class(%XML.Security.DataReference).Create(encdata2)
 do reflist.AddReference(dataref2)
  1. <ReferenceList> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,请指定您的引用列表实例。
 do ..SecurityOut.AddSecurityElement(reflist)
0
0 105
文章 姚 鑫 · 九月 23, 2024 2m read

第三十一章 使用派生密钥令牌进行加密和签名 - 变体:创建隐式 <DerivedKeyToken>

变体:创建隐式 <DerivedKeyToken>

还可以创建隐式 <DerivedKeyToken>,这是引用 <DerivedKeyToken> 的快捷方法。在此方法中:

  • 消息中不包含 <DerivedKeyToken>
  • 在使用 <DerivedKeyToken> 的元素中,<SecurityTokenReference> 元素指定 Nonce 属性,该属性包含用于 <DerivedKeyToken>nonce 值。这向消息接收者表明派生密钥令牌是隐含的,并且是从引用的令牌派生的。

要创建隐式 <DerivedKeyToken>,请使用前面描述的一般过程,但有两处更改:

  1. 对于派生的密钥令牌实例,将 Implied 属性设置为 1
 set dkt.Implied=1
  1. 请勿将 <DerivedKeyToken> 元素添加到 WS-Security 标头元素。

使用 <DerivedKeyToken> 的方式与将其包含在消息中的方式完全相同。

变体:引用 <EncryptedKey>SHA1 哈希

在此变体中(仅适用于 Web 服务),发送者不在消息中包含 <EncryptedKey> 元素,而是引用密钥的 SHA1 哈希。Web 服务可以引用在入站消息中收到的 <EncryptedKey> 元素。

使用前面的一般程序,但需做以下更改:

  • 步骤 2-4 是可选的。.
  • 省略步骤 5(不要添加 <EncryptedKey>)。
  • 在步骤 6 中,当您使用 Create() 创建派生密钥令牌时,若要使用从客户端收到的 <EncryptedKey>,请省略第一个参数。或者,如果您已创建 <EncryptedKey>,请将其用作第一个参数。

指定 $$$SOAPWSReferenceEncryptedKeySHA1 作为第二个参数。

例如,要使用从 Web 客户端收到的消息中的第一个 <EncryptedKey> 元素:

 set refopt=$$$SOAPWSReferenceEncryptedKeySHA1
 set dkenc=##class(%SOAP.WSSC.DerivedKeyToken).Create(,refopt)
0
0 66
文章 姚 鑫 · 九月 22, 2024 3m read

第三十章 使用派生密钥令牌进行加密和签名

IRIS 支持 WS-SecureConversation 1.4 定义的 <DerivedKeyToken> 元素。可以创建并使用<DerivedKeyToken> 元素进行加密和签名,作为前三个主题中描述的方法的替代。

通常,会同时执行加密和签名。为简单起见,本主题分别介绍这些任务。有关结合加密和签名的信息,请参阅结合加密和签名。

概述

<DerivedKeyToken> 元素旨在携带发送者和接收者可以独立使用的信息来生成相同的对称密钥。这些方可以使用该对称密钥对 SOAP 消息的指定部分进行加密、签名或同时执行这两种操作。

要生成和使用 <DerivedKeyToken>,请执行以下操作:

  1. 生成一个对称密钥以供临时使用。
  2. 使用要向其发送消息的实体的公钥来加密对称密钥。这将创建一个 <EncryptedKey>元素。

可以从该实体的请求消息中包含的 X.509 证书中获取公钥。或者可以提前获取它。

  1. 通过 P_SHA1 算法从原始对称密钥计算出一个新的对称密钥。

这将创建一个引用 <EncryptedKey> 元素的 <DerivedKeyToken> 元素。

  1. 使用新的对称密钥进行加密或签名。

对这些活动使用不同的对称密钥被认为是一种很好的做法,这样就可以减少用于分析的数据量。

  1. 在消息中包含 <EncryptedKey>元素和 <DerivedKeyToken>

IRIS 中,派生密钥令牌也可以基于另一个派生密钥令牌。

创建并添加 <DerivedKeyToken>

作为参考,本节描述了后面几节中需要的常见活动。它描述了如何创建 <DerivedKeyToken> 并将其添加到 WS-Security 标头。您可以使用以下步骤或各小节中描述的变体。

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 获取要向其发送消息的实体的凭证集。请参阅以编程方式检索凭证集。
 Set x509alias = "servernopassword" 
 Set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
  1. 根据凭证集创建加密密钥。为此,调用 %XML.Security.EncryptedKeyCreateX509() 类方法,并将第二个参数指定为 $$$SOAPWSEncryptNone。例如:
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(credset,$$$SOAPWSEncryptNone)

此方法生成一个对称密钥,并返回 %XML.Security.EncryptedKey的实例,该实例表示 <EncryptedKey> 标头元素。此标头元素包含对称密钥,由给定凭证集中的公钥加密。

当创建加密密钥作为派生密钥的基础时,请始终指定 $$$SOAPWSEncryptNone"" 作为 CreateX509() 的第二个参数。

  1. 可选择修改加密密钥实例以使用不同的算法。请参阅指定块加密算法和指定密钥传输算法。

  2. <EncryptedKey> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,指定 %XML.Security.EncryptedKey的实例。

 do ..SecurityOut.AddSecurityElement(enckey)
  1. 根据加密密钥创建派生密钥令牌。为此,调用 %SOAP.WSSC.DerivedKeyToken的 Create() 方法。此方法采用两个参数:

a. 作为基础使用的加密密钥。

b. 指定派生密钥如何引用该加密密钥的引用选项。在此基本过程中,使用 $$$SOAPWSReferenceEncryptedKey

 set refopt=$$$SOAPWSReferenceEncryptedKey
 set dkenc=##class(%SOAP.WSSC.DerivedKeyToken).Create(enckey,refopt)

此方法在返回代表 <DerivedKeyToken>元素的 %SOAP.WSSC.DerivedKeyToken的实例。

  1. &<DerivedKeyToken> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,指定 %SOAP.WSSC.DerivedKeyToken的实例。
 do ..SecurityOut.AddSecurityElement(dkenc)
  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。
1
0 120
文章 姚 鑫 · 九月 19, 2024 2m read

第二十九章 添加数字签名 - 指定 <KeyInfo> 的规范化方法

默认情况下,<KeyInfo> 元素使用Exclusive XML Canonicalization进行规范化,<KeyInfo> 元素包括以下内容:

<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">

要使用包容性 XML 规范化来规范化此元素,请执行以下操作:

 Set sig.SignedInfo.CanonicalizationMethod.Algorithm=$$$SOAPWSc14n

其中 sig%XML.Security.Signature 的实例。

在这种情况下, <KeyInfo> 包含以下内容:

<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">

添加签名确认

WS-Security 1.1 <SignatureConfirmation> 功能使 Web 客户端能够确保收到的 SOAP 消息是响应 Web 客户端发送的原始请求而生成的。客户端请求通常经过签名,但并非必须如此。在此机制中,Web 服务将 <SignatureConfirmation> 元素添加到安全标头元素,Web 客户端可以检查该 <SignatureConfirmation>元素。

对于 Web 服务,要将<SignatureConfirmation> 元素添加到安全标头元素:

  1. 调用 Web 服务的 WSAddSignatureConfirmation() 方法。对于参数,请指定安全标头元素的主签名。例如:
 do ..WSAddSignatureConfirmation(sig)
  1. 照常发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。

此方法将 WS-Security 1.1 <SignatureConfirmation> 元素添加到出站消息中。它为 SecurityIn 中收到的每个 <Signature>SecurityOut 属性添加一个 <SignatureConfirmation> 元素。

如果 SecurityIn 不包含签名,则会添加不带 Value 属性的 <SignatureConfirmation> 元素,这是 WS-Security 1.1 的要求。

有关验证<SignatureConfirmation> 元素的信息,请参阅检查签名确认。

0
0 85
文章 姚 鑫 · 九月 18, 2024 2m read

第二十八章 添加数字签名 - 指定摘要方法

指定摘要方法

默认情况下,签名的摘要值是通过 SHA-1 算法计算的,安全标头中的 <Signature> 元素包含如下内容:

   <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
   <DigestValue>waSMFeYMruQn9XHx85HqunhMGIA=</DigestValue>

可以为签名指定不同的摘要方法。为此,调用 %XML.Security.Signature 实例的 SetDigestMethod() 方法。对于参数,请使用以下宏之一(包含在 %soap.inc 文件中):

  • $$$SOAPWSsha1 (the default)

-$$$SOAPWSsha256

  • $$$SOAPWSsha384

  • $$$SOAPWSsha512

 do sig.SetDigestMethod($$$SOAPWSsha256)

指定签名方法

默认情况下,签名值是通过 RSA-SHA256 算法计算的,安全标头中的 <Signature> 元素包含如下内容:

   <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256"></SignatureMethod>
...
   <SignatureValue>J+gACmdjkJxaq2hJqA[parts omitted]</SignatureValue>

可以为签名方法指定不同的算法。为此,调用 %XML.Security.Signature实例的 SetSignatureMethod() 方法。对于参数,请使用以下宏之一(包含在 %soap.inc 文件中):

  • $$$SOAPWSrsasha1

  • $$$SOAPWSrsasha256 (the default)

  • $$$SOAPWSrsasha384

  • $$$SOAPWSrsasha512

  • $$$SOAPWShmacsha256

  • $$$SOAPWShmacsha384

  • $$$SOAPWShmacsha512

 do sig.SetSignatureMethod($$$SOAPWSrsasha512)

请注意,可以修改默认签名算法。要进行此操作,请访问管理门户,单击系统管理,然后单击安全,然后单击系统安全,然后单击系统范围安全参数。指定默认签名算法的选项标记为默认签名哈希。

0
0 81
文章 姚 鑫 · 九月 17, 2024 2m read

第二十七章 添加数字签名 - 变体:使用签名的 SAML 断言

要添加在签名的 SAML 断言中使用证书的数字签名,请执行以下操作:

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 如果要对任何安全标头元素进行签名,请创建这些安全标头元素。例如:
 set utoken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
  1. 使用 Holder-of-key 方法的<SubjectConfirmation> 元素创建签名的 SAML 断言。请参阅创建和添加 SAML 令牌。
  2. 创建 <Signature> 元素。创建时,使用已签名的 SAML 断言作为 CreateX509() 类方法的第一个参数。例如:
 set signature=##class(%XML.Security.EncryptedKey).CreateX509(signedassertion)
  1. 将数字签名添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于参数,请指定上一步中创建的签名对象。例如:
 do ..SecurityOut.AddSecurityElement(dsig)
  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。

将数字签名应用于特定消息部分

默认情况下,当创建数字签名并将其添加到 WS-Security 标头元素时,该签名将应用于 SOAP 主体、标头中的 <Timestamp> 元素(如果存在)以及任何 WS-Addressing 标头元素。

要指定签名适用的部分,请使用前面描述的任一过程,但有一个变体:创建签名时,使用第二个参数 (signatureOptions) 指定要签名的消息部分。将此参数指定为以下任何宏的二进制组合(包含在 %soap.inc 文件中):

  • $$$SOAPWSIncludeNone

$$$SOAPWSIncludeDefault (which equals $$$SOAPWSIncludeSoapBody + $$$SOAPWSIncludeTimestamp + $$$SOAPWSIncludeAddressing)

  • $$$SOAPWSIncludeSoapBody

  • $$$SOAPWSIncludeTimestamp

  • $$$SOAPWSIncludeAddressing

  • $$$SOAPWSIncludeAction

  • $$$SOAPWSIncludeFaultTo

  • $$$SOAPWSIncludeFrom

  • $$$SOAPWSIncludeMessageId

  • $$$SOAPWSIncludeRelatesTo

  • $$$SOAPWSIncludeReplyTo

  • $$$SOAPWSIncludeTo

  • $$$SOAPWSIncludeRMHeaders

要组合宏,请使用加号 (+) 和减号 (-)。例如:

$$$SOAPWSIncludeSoapBody+$$$SOAPWSIncludeTimestamp

注意:这些选项既适用于 CreateX509() 也适用于 Create() 方法;后者在使用派生密钥令牌进行加密和签名中进行了讨论。

 set ts=##class(%SOAP.Security.Timestamp).Create()
 do ..SecurityOut.AddSecurityElement(ts)
 set x509alias = "servercred" 
 set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
 
 set parts=$$$SOAPWSIncludeSoapBody + $$$SOAPWSIncludeTimestamp
 set signature=##class(%XML.Security.Signature).CreateX509(cred,parts)
0
0 65
文章 姚 鑫 · 九月 15, 2024 4m read

第二十六章 添加数字签名 - 示例

示例

此示例显示了对其响应消息进行签名的 Web 服务。

为了使此示例在自己的环境中运行,请首先执行以下操作:

  • 为服务器创建证书。
  • 将此证书加载到服务器端的 IRIS 中,创建名为 servercred 的凭证。执行此操作时,还要加载私钥文件并提供其密码(这样 Web 服务在签署其响应消息时就不必提供该密码。)

Web 服务指的是具有此确切名称的 IRIS 凭证集。

Class DSig.DivideWS Extends %SOAP.WebService
{

///  Name of the Web service.
Parameter SERVICENAME = "DigitalSignatureDemo";

///  SOAP namespace for the Web service
Parameter NAMESPACE = "http://www.myapp.org";

/// use in documentation
Method Divide(arg1 As %Numeric = 2, arg2 As %Numeric = 8) As %Numeric [ WebMethod ]
{
 Do ..SignResponses()
 Try {
  Set ans=arg1 / arg2
  }Catch{
    Do ..ApplicationError("division error")
  }
 Quit ans
}

/// use in documentation
/// signs and includes a binary security token
Method SignResponses()
{
 //Add timestamp because that's commonly done
 Set ts=##class(%SOAP.Security.Timestamp).Create()
 Do ..SecurityOut.AddSecurityElement(ts)

 //access previously stored server certificate & private key file
 //no need to use private key file password, because that has been saved
 Set x509alias = "servercred" 
 Set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
 set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(cred)
 do ..SecurityOut.AddSecurityElement(bst)

 //Create WS-Security Signature object
 Set signature=##class(%XML.Security.Signature).CreateX509(bst)
 
 //Add WS-Security Signature object to the outbound message
 Do ..SecurityOut.AddSecurityElement(signature)
 Quit
}


///  Create our own method to produce application specific SOAP faults.
Method ApplicationError(detail As %String)
{
    Set fault=##class(%SOAP.Fault).%New()
    Set fault.faultcode=$$$FAULTServer
    Set fault.detail=detail
    Set fault.faultstring="Application error"
    // ReturnFault must be called to send the fault to the client.
    // ReturnFault will not return here.
    Do ..ReturnFault(fault)
}


}

使用带签名的证书的其他方法

在上一节讨论的基本过程中,使用 <BinarySecurityToken> 包含序列化、base-64 编码格式的证书。除了包含证书之外,还可以使用标识证书的信息。或者,可以将证书包含在签名的 SAML 断言中。本节讨论了这些变体。

变体:使用可识别证书的信息

可以包含标识证书的信息,而不是在邮件中包含证书。收件人使用此信息从适当的位置检索证书。为此,请使用上一节中的步骤,并进行以下更改:

  • 跳过步骤 45。也就是说,不要添加 <BinarySecurityToken>
  • 在步骤 6(创建签名)中,使用步骤 1 中设置的凭证(而不是二进制安全令牌)作为 CreateX509() 的第一个参数。例如:
 set dsig=##class(%XML.Security.Signature).CreateX509(credset,,referenceOption)

对于第三个参数(referenceOption),可以指定<Signature> 元素如何使用证书。

如果指定一个凭据集作为第一个参数(正如我们在此变体中所做的那样),则referenceOption的默认值为$$$SOAPWSReferenceThumbprint。 可选地指定一个值,如X.509凭据的参考选项中所述。 您可以使用除$$$SOAPWSReferenceDirect之外的任何值。

示例

此示例是本主题中先前示例的变体。

Method SignResponses()
{
 //Add timestamp because that's commonly done
 Set ts=##class(%SOAP.Security.Timestamp).Create()
 Do ..SecurityOut.AddSecurityElement(ts)

 //access previously stored server certificate & private key file
 //no need to use private key file password, because that has been saved
 Set x509alias = "servercred" 
 Set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)

 //Create WS-Security Signature object
 Set signature=##class(%XML.Security.Signature).CreateX509(cred)
 
 //Add WS-Security Signature object to the outbound message
 Do ..SecurityOut.AddSecurityElement(signature)
 Quit
}

在这种情况下,Web 服务发送如下响应消息:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope [parts omitted]>
  <SOAP-ENV:Header>
    <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <Timestamp xmlns="[parts omitted]oasis-200401-wss-wssecurity-utility-1.0.xsd" 
                 wsu:Id="Timestamp-48CEE53E-E6C3-456C-9214-B7D533B2663F">
        <Created>2010-03-19T14:35:06Z</Created>
        <Expires>2010-03-19T14:40:06Z</Expires>
      </Timestamp>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
          </CanonicalizationMethod>
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256"></SignatureMethod>
            <Reference URI="#Timestamp-48CEE53E-E6C3-456C-9214-B7D533B2663F">
              <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
              </Transforms>
              <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
                <DigestValue>waSMFeYMruQn9XHx85HqunhMGIA=</DigestValue>
            </Reference>
            <Reference URI="#Body-73F08A5C-0FFD-4FE9-AC15-254423DBA6A2">
              <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
              </Transforms>
              <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
                <DigestValue>wDCqAzy5bLKKF+Rt0+YV/gxTQws=</DigestValue>
            </Reference>
          </SignedInfo>
          <SignatureValue>j6vtht/[parts omitted]trCQ==</SignatureValue>
          <KeyInfo>
            <SecurityTokenReference 
            xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
              <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                             ValueType="[parts omitted]#ThumbprintSHA1">
                   WeCnU2sMyOXfHH8CHTLjNTQQnGQ=
              </KeyIdentifier>
            </SecurityTokenReference>
          </KeyInfo>
        </Signature>
      </Security>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body wsu:Id="Body-73F08A5C-0FFD-4FE9-AC15-254423DBA6A2">
      [omitted]
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
0
0 64
文章 姚 鑫 · 九月 14, 2024 4m read

第二十五章 添加数字签名

本主题介绍如何向 IRIS Web 服务和 Web 客户端发送的 SOAP 消息添加数字签名。

通常,会同时执行加密和签名。为简单起见,本主题仅介绍签名。有关结合加密和签名的信息,请参阅主题结合加密和签名。

主题使用派生密钥令牌进行加密和签名描述了向 SOAP 消息添加数字签名的另一种方法。

数字签名概述

可以使用数字签名来检测消息是否被篡改,或者简单地验证消息的某一部分是否确实由所列实体生成。与传统的手工签名一样,数字签名是对文档的附加,只有文档的创建者才能创建,并且不容易伪造。

IRISSOAP 消息的数字签名的支持基于 WS-Security1.1。反过来,WS-Security 遵循 XML 签名规范。根据后者的规范,要对 XML 文档进行签名:

  1. 使用摘要函数来计算文档一个或多个部分的哈希值。
  2. 将摘要值连接起来。
  3. 使用私钥加密串联摘要。(这是只有才能执行的计算。)
  4. 创建 <Signature> 元素,其中包含以下信息:
  • 对已签名部分的引用(以表明该签名适用于消息的哪些部分)。
  • 加密的摘要值。
  • 使接收者能够识别用于解密加密摘要值的公钥的信息。

此信息可以包含在<Signature>元素中,或者 <Signature> 元素可以包含对包含 X.509 证书或签名的 SAML 断言的二进制安全令牌的直接引用。在后一种情况下,必须在添加 <Signature>元素之前将安全令牌添加到消息中。

此信息还可以让收件人验证您是公钥/私钥对的所有者。

使用派生密钥令牌进行加密和签名主题介绍了一种向 SOAP 消息添加数字签名的替代方法。消息本身的细节各不相同,但一般过程是相同的,并遵循 XML 签名规范:生成签名部分的摘要,加密摘要,并包含一个 <Signature> 元素,其中包含使收件人能够验证签名和解密加密摘要的信息。

添加数字签名

要对 SOAP 消息进行数字签名,可以使用此处的基本过程或本主题后续部分中描述的变体。

具体过程如下:

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 如果要对任何安全标头元素进行签名,请创建这些安全标头元素。例如:
 set utoken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
  1. 创建 %SYS.X509Credentials 实例,如以编程方式检索凭证集中所述。此 IRIS 凭证集必须包含自己的证书,并且必须提供私钥密码(如果尚未加载)。例如:
 Set x509alias = "servercred" 
 Set pwd = "mypassword" 
 Set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,mypassword)
  1. 创建包含与该凭证集关联的证书的二进制安全令牌。为此,调用 %SOAP.Security.BinarySecurityTokenOCreateX509Token() 类方法。例如:
 set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)

此方法返回代表 <BinarySecurityToken> 标头元素的 %SOAP.Security.BinarySecurityToken实例。

  1. 将此令牌添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于方法参数,请使用刚刚创建的令牌。例如:
 do ..SecurityOut.AddSecurityElement(bst)
  1. 根据二进制安全令牌创建 <Signature> 元素。为此,调用 %XML.Security.Signature的 CreateX509() 类方法。例如:
 set dsig=##class(%XML.Security.Signature).CreateX509(bst)

此方法返回 %XML.Security.Signature 的实例,该实例表示 &<Signature>标头元素。<Signature> 元素适用于消息的一组默认部分;可以指定一组不同的部分。

正式地,该方法具有以下签名:

classmethod CreateX509(credentials As %SYS.X509Credentials = "", 
                       signatureOptions As %Integer, 
                       referenceOption As %Integer, 
                       Output status As %Status) as %XML.Security.Signature
  • credentials - 凭据要么是实例中的 %SYS.X509Credentials,要么是实例中的 %SAML.Assertion,要么是实例中的 %SOAP.Security.BinarySecurityToken
  • signatureOptions 指定要签名的部分。此选项在将数字签名应用于特定消息部分中进行了描述。
  • referenceOption 指定要创建的引用类型。有关详细信息,请参阅 X.509 凭证的引用选项。
  • status 表示该方法是否成功。
  1. 将数字签名添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于参数,请指定上一步中创建的签名对象。例如:
 do ..SecurityOut.AddSecurityElement(dsig)
  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。
0
0 98
文章 姚 鑫 · 九月 13, 2024 3m read

第二十四章 加密安全标头元素 - 基本示例

以下示例调用 Web 客户端并发送已加密的 <UsernameToken>。在此示例中,正文未加密。

  Set client=##class(XMLEncrSecHeader.Client.XMLEncrSecHeaderSoap).%New()

  // Create UsernameToken
  set user="_SYSTEM"
  set pwd="SYS"
  set userToken=##class(%SOAP.Security.UsernameToken).Create(user,pwd)
 
  //get credentials for encryption
  set cred = ##class(%SYS.X509Credentials).GetByAlias("servernopassword") 

  //get EncryptedKey element and add it
  set encropt=$$$SOAPWSEncryptNone   ; means do not encrypt body
  set enckey=##class(%XML.Security.EncryptedKey).CreateX509(cred,encropt)

  //create EncryptedData and add a reference to it from EncryptedKey
  set encdata=##class(%XML.Security.EncryptedData).Create(,userToken)
  set dataref=##class(%XML.Security.DataReference).Create(encdata)
  do enckey.AddReference(dataref)

  //add EncryptedKey to security header
  do client.SecurityOut.AddSecurityElement(enckey) 
  //add UsernameToken and place it after EncryptedKey
  do client.SecurityOut.AddSecurityElement(userToken,enckey) 

  Quit client.Divide(1,2)

该客户端发送如下消息:

<?xml version="1.0" encoding="UTF-8" ?>
   <SOAP-ENV:Envelope [parts omitted]>  
      <SOAP-ENV:Header>
         <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
               <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
                  <DigestMethod 
                    xmlns="http://www.w3.org/2000/09/xmldsig#"
                    Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
                  </DigestMethod>
               </EncryptionMethod>
               <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <SecurityTokenReference 
                       xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                     <KeyIdentifier EncodingType="[parts omitted]#Base64Binary"    
                            ValueType="[parts omitted]#ThumbprintSHA1">[omitted]</KeyIdentifier>
                  </SecurityTokenReference>
               </KeyInfo>
               <CipherData>
                  <CipherValue>pftET8jFDEjNC2x[parts omitted]xEjNC2==</CipherValue>
               </CipherData>
               <ReferenceList>
                  <DataReference URI="#Enc-61000920-44DE-471E-B39C-6D08CB17FDC2">
                  </DataReference>
               </ReferenceList>
            </EncryptedKey>
            <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                   Id="Enc-61000920-44DE-471E-B39C-6D08CB17FDC2" 
                   Type="http://www.w3.org/2001/04/xmlenc#Element">
               <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
               </EncryptionMethod>
               <CipherData>
                  <CipherValue>wW3ZM5tgPD[parts omitted]tgPD==</CipherValue>
               </CipherData>
            </EncryptedData>
         </Security>  
      </SOAP-ENV:Header>  
      <SOAP-ENV:Body>
         [omitted]
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>

作为一个简单的变化,请考虑上一节中的过程。假设我们在步骤 4 中执行以下操作,并且不做其他更改:

 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(credset)

在这种情况下,来自客户端的消息包括加密正文和加密的 <UsernameToken>:

<?xml version="1.0" encoding="UTF-8" ?>
   <SOAP-ENV:Envelope [parts omitted]>  
      <SOAP-ENV:Header>
         <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
               <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
                  <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 
                        Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
                  </DigestMethod>
               </EncryptionMethod>
               <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <SecurityTokenReference 
                     xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                     <KeyIdentifier EncodingType="[parts omitted]#Base64Binary" 
                         ValueType="[parts omitted]#ThumbprintSHA1">
                               5a[parts omitted]dM1r6cM=
                     </KeyIdentifier>
                  </SecurityTokenReference>
               </KeyInfo>
               <CipherData>
                  <CipherValue>TB8uavpr[parts omitted]nZBiMCcg==</CipherValue>
               </CipherData>
               <ReferenceList>
                  <DataReference URI="#Enc-43FE435F-D1D5-4088-A343-0E76D154615A"></DataReference>
                  <DataReference URI="#Enc-55FE109A-3C14-42EB-822B-539E380EDE48"></DataReference>
               </ReferenceList>
            </EncryptedKey>
            <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                 Id="Enc-43FE435F-D1D5-4088-A343-0E76D154615A" 
                 Type="http://www.w3.org/2001/04/xmlenc#Element">
               <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
               </EncryptionMethod>
               <CipherData>
                  <CipherValue>G+X7dqI[parts omitted]nojroQ==</CipherValue>
               </CipherData>
            </EncryptedData>
         </Security>  
      </SOAP-ENV:Header>  
      <SOAP-ENV:Body>
         <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                  Id="Enc-55FE109A-3C14-42EB-822B-539E380EDE48" 
                  Type="http://www.w3.org/2001/04/xmlenc#Content">
            <EncryptionMethod Algorithm="[parts omitted]aes128-cbc"></EncryptionMethod>
            <CipherData>
               <CipherValue>YJbzyi[parts omitted]NhJoln==</CipherValue>
            </CipherData>
         </EncryptedData>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>

与上一个示例相比,在本例中 <EncryptedKey> 元素包含对两个 <EncryptedData> 元素的引用。一个是安全标头中的 <EncryptedData> 元素,其中包含 <UsernameToken>;此引用是手动创建和添加的。另一个是 SOAP 主体中的 <EncryptedData> 元素;此引用是自动添加的。

0
0 73
文章 姚 鑫 · 九月 12, 2024 3m read

第二十三章 加密安全标头元素

本主题介绍如何加密 Web 服务和 Web 客户端发送的消息中的 WS-Security 标头内的元素。(此处描述的工具也可单独使用或与安全标头元素结合使用来加密 SOAP 主体。)

通常,会同时执行加密和签名。为简单起见,本主题仅介绍加密。有关结合加密和签名的信息,请参阅结合加密和签名。

使用派生密钥令牌进行加密和签名主题描述了加密 SOAP 消息部分内容的另一种方法。

加密安全标头元素

与上一主题中显示的加密技术不同,加密 WS-Security 标头元素的过程要求您指定 <EncryptedData> 元素如何连接到相应的 <EncryptedKey> 元素。

要加密安全标头元素,请执行以下操作:

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 创建要加密的标头元素。例如:
 set userToken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
  1. 获取包含将接收 SOAP 消息的实体的公钥的凭证集。请参阅以编程方式检索凭证集。
 set credset=..SecurityIn.Signature.X509Credentials

请务必检查返回对象的类型,看它是否是 %SYS.X509Credential的实例,如以编程方式检索凭据集中所述。

  1. 根据凭证集创建加密密钥。为此,调用 %XML.Security.EncryptedKeyCreateX509() 类方法,并可选择指定第二个参数。例如:
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(credset,$$$SOAPWSEncryptNone)

此方法生成一个对称密钥,返回 %XML.Security.EncryptedKey 的实例,该实例表示 <EncryptedKey> 标头元素。此标头元素包含对称密钥,由给定凭证集中的公钥加密。

第二个参数指定此密钥是否加密 SOAP 主体(除了密钥的任何其他用途之外)。值 $$$SOAPWSEncryptNone 表示此密钥不会用于加密 SOAP 主体。如果省略此参数,则 SOAP 主体也会被加密。

  1. 可选择修改加密密钥实例以使用不同的算法。请参阅指定块加密算法和指定密钥传输算法。
  2. 对于每个要加密的安全标头元素,根据该元素创建一个 <EncryptedData> 元素。为此,调用 %XML.Security.EncryptedDataCreate() 类方法。在此过程中,仅指定第二个参数,即要加密的安全标头元素。例如:
 set encdata=##class(%XML.Security.EncryptedData).Create(,userToken)
  1. 对于 <EncryptedKey>,添加对 <EncryptedData> 元素的引用。对每个 <EncryptedData> 元素执行以下操作:

a. 调用 %XML.Security.DataReferenceCreate() 类方法并提供加密数据实例作为参数。

b. 调用加密密钥实例的 AddReference() 方法并提供数据引用作为参数。

 set dataref=##class(%XML.Security.DataReference).Create(encdata)
 do enckey.AddReference(dataref)

此步骤更新加密密钥实例以包含指向加密数据实例的指针。

如果此 <EncryptedKey> 也加密 SOAP 主体,它会自动在 <Body> 中包含对 <EncryptedData> 元素的引用。

  1. <EncryptedKey> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,指定 %XML.Security.EncryptedKey 的实例。
 do ..SecurityOut.AddSecurityElement(enckey)
  1. 将加密的安全标头元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。在本例中,指定两个参数:

a. 要包含的安全标头元素(而不是基于该元素 %XML.Security.EncryptedData 的实例)。

b. 加密密钥实例。第二个参数指定第一个参数指定的项的放置位置。如果参数为 AB,则 IRIS 确保 AB 之后。指定此项以便收件人首先处理加密密钥,然后再处理依赖于它的加密安全标头元素。

 do ..SecurityOut.AddSecurityElement(userToken,enckey)
0
0 69
文章 姚 鑫 · 九月 11, 2024 3m read

第二十二章 加密 SOAP 主体 - 变体:使用签名的 SAML 断言

要使用签名的 SAML 断言中的证书中包含的公钥进行加密,请执行以下操作:

  1. 跳过前面步骤中的步骤 1–4
  2. 使用 Holder-of-key 方法的 <SubjectConfirmation>元素创建签名的 SAML 断言。请参阅创建和添加 SAML 令牌。
  3. 创建 <EncryptedKey> 元素。执行此操作时,使用签名的 SAML 断言作为 CreateX509() 类方法的第一个参数。例如:
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(signedassertion)
  1. 继续前面步骤中的步骤5。

消息加密示例

在此示例中,Web 客户端(未显示)发送签名的请求消息,而 Web 服务发送加密响应。

Web 服务从请求消息签名中的客户端证书中获取公钥,并使用该公钥在其响应中添加一个加密的 <EncryptedKey> 元素。 <EncryptedKey> 元素使用客户端的公钥加密,它包含用于加密响应消息正文的对称密钥。

Web服务如下:

Class XMLEncr.DivideWS Extends %SOAP.WebService
{

Parameter SECURITYIN = "REQUIRE";

Parameter SERVICENAME = "XMLEncryptionDemo";

Parameter NAMESPACE = "http://www.myapp.org";

Method Divide(arg1 As %Numeric = 2, arg2 As %Numeric = 8) As %Numeric [ WebMethod ]
{
  Do ..EncryptBody() 
  Try {
      Set ans=arg1 / arg2
      } Catch {
      Do ..ApplicationError("division error")
      }
  Quit ans
}

Method EncryptBody()
{
  //Retrieve X.509 certificate from the signature of the inbound request
  Set clientsig = ..SecurityIn.Signature
  Set clientcred = clientsig.X509Credentials
  set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(clientcred)
  do ..SecurityOut.AddSecurityElement(bst)
  
  //generate a symmetric key, encrypt that with the public key of
  //the certificate contained in the token, and create an 
  //<EncryptedKey> element with a direct reference to the token (default)
  Set enc=##class(%XML.Security.EncryptedKey).CreateX509(bst)
  
  //add the <EncryptedKey> element to the security header
  Do ..SecurityOut.AddSecurityElement(enc)
}

///  Create our own method to produce application specific SOAP faults.
Method ApplicationError(detail As %String)
{
    //details omitted
}

}

该服务发送如下响应消息:

<?xml version="1.0" encoding="UTF-8" ?>
   <SOAP-ENV:Envelope [parts omitted]>  
      <SOAP-ENV:Header>
         <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <BinarySecurityToken wsu:Id="SecurityToken-4EC1997A-AD6B-48E3-9E91-8D50C8EA3B53" 
                                 EncodingType="[parts omitted]#Base64Binary" 
                                 ValueType="[parts omitted]#X509v3">
                         MIICnDCCAYQ[parts omitted]ngHKNhh
            </BinarySecurityToken>
            <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
               <EncryptionMethod Algorithm="[parts omitted]xmlenc#rsa-oaep-mgf1p">
                  <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 
                                Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
               </DigestMethod>
               </EncryptionMethod>
               <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <SecurityTokenReference 
                        xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
                     <Reference URI="#SecurityToken-4EC1997A-AD6B-48E3-9E91-8D50C8EA3B53" 
                                ValueType="[parts omitted]#X509v3"></Reference>
                  </SecurityTokenReference>
               </KeyInfo>
               <CipherData>
                  <CipherValue>WtE[parts omitted]bSyvg==</CipherValue>
               </CipherData>
               <ReferenceList>
                  <DataReference URI="#Enc-143BBBAA-B75D-49EB-86AC-B414D818109F"></DataReference>
               </ReferenceList>
            </EncryptedKey>
         </Security>  
      </SOAP-ENV:Header>  
      <SOAP-ENV:Body>
         <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" 
                        Id="Enc-143BBBAA-B75D-49EB-86AC-B414D818109F" 
                        Type="http://www.w3.org/2001/04/xmlenc#Content">
            <EncryptionMethod Algorithm="[parts omitted]#aes128-cbc"></EncryptionMethod>
            <CipherData>
               <CipherValue>MLwR6hvKE0gon[parts omitted]8njiQ==</CipherValue>
            </CipherData>
         </EncryptedData>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>

指定块加密算法

默认情况下,消息本身使用 $$$SOAPWSaes128cbc 加密。您可以指定不同的算法。为此,请设置 %XML.Security.EncryptedKey实例的算法属性。

可能的值是 $$$SOAPWSaes128cbc(默认值)、$$$SOAPWSaes192cbc$$$SOAPWSaes256cbc

例如:

 set enckey.Algorithm=$$$SOAPWSaes256cbc

如其他地方所述,当在其他场景中创建 <EncryptedKey> 时,此信息也适用。

指定密钥传输算法

密钥传输算法是用于对称密钥的公钥加密算法(请参阅 https://www.w3.org/TR/xmlenc-core/)。默认情况下,这是 $$$SOAPWSrsaoaep。可以改用 $$$SOAPWSrsa15。为此,请调用上一步中创建的 %XML.Security.EncryptedKey实例的 SetEncryptionMethod() 方法。此方法的参数可以是 $$$SOAPWSrsaoaep(默认值)或 $$$SOAPWSrsa15

例如:

 do enckey.SetEncryptionMethod($$$SOAPWSrsa15)

如其他地方所述,当您在其他场景中创建<EncryptedKey> 时,此信息也适用。

0
0 101
文章 姚 鑫 · 九月 10, 2024 3m read

第二十一章 加密 SOAP 主体 - 变体:使用可识别证书的信息

<BinarySecurityToken> 包含序列化、base-64 编码格式的证书。可以忽略此令牌,而改用标识证书的信息;接收方使用此信息从相应位置检索证书。为此,请使用上述步骤,并进行以下更改:

  • 跳过步骤 34。也就是说,不要添加 <BinarySecurityToken>
  • 在步骤 5(创建加密密钥)中,使用步骤 1 中设置的凭据(而不是二进制安全令牌)作为 CreateX509() 的第一个参数。例如:
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(credset,,referenceOption)

对于第三个参数(referenceOption),可以指定<Signature> 元素如何使用证书。

如果指定一个凭据集作为第一个参数(正如我们在此变体中所做的那样),则referenceOption的默认值为$$$SOAPWSReferenceThumbprint。 可以选择指定一个值,如本节所述。 可以使用除$$$SOAPWSReferenceDirect之外的任何值。

X.509 证书的参考选项

WS-Security 标头简介部分介绍了在 SOAP 消息中使用证书的一种方法。在该示例中,数字签名由两个标头元素组成:

  • <BinarySecurityToken> 元素,以序列化的base-64 编码形式携带证书。
  • <Signature> 元素,带有签名并且包含对二进制安全令牌的直接引用。

还有其他可能的引用形式。例如,<Signature> 可以包含证书的指纹,在这种情况下,消息中不需要 <BinarySecurityToken>

创建加密密钥、数字签名或 SAML 断言时,可以指定 referenceOption 参数,该参数控制新创建的元素如何使用凭证中包含的证书(或更具体地说,密钥材料)。

作为参考,此参数可以具有以下任意值。这些值是 %soap.inc 包含文件中定义的宏:

$$$SOAPWSReferenceDirect

该元素包含对二进制安全令牌的直接引用。具体来说,<KeyInfo> 元素由 <SecurityTokenReference>子元素和<Reference> 子元素组成,其中 <SecurityTokenReference> 子元素的 URI 属性是对 <BinarySecurityToken> 的本地引用。要使用此选项,还必须确保将安全令牌添加到 WS-Security 标头;详细信息在相关部分中给出。

$$$SOAPWSReferenceThumbprint

该元素包括 X.509 证书的 SHA-1 指纹。

$$$SOAPWSReferenceKeyIdentifier

该元素包括 X.509 证书的 SubjectKeyIdentifier

$$$SOAPWSReferenceIssuerSerial

该元素包括一个 <KeyInfo> 元素,该元素带有一个 <SecurityTokenReference> 子元素,该子元素还有一个<X509Data> 子元素,该子元素包含一个 <X509IssuerSerial> 元素。

$$$KeyInfoX509Certificate

该元素包含一个 <KeyInfo> 元素,该元素带有一个 &<X509Data> 子元素,而该子元素又包含一个<X509Certificate> 元素。WS-Security 规范不建议将 <Signature> and <EncryptedKey> 元素用于此用途,但可以将其用于<Assertion> 元素。

$$$KeyInfoX509IssuerSerial

该元素包含一个 <KeyInfo> 元素,该元素带有一个<X509Data> 子元素,该子元素包含一个 <X509IssuerSerial>元素。WS-Security 规范不建议将 <Signature> and <EncryptedKey> 元素用于此用法,但可以将其用于 <Assertion> 元素。

$$$KeyInfoX509SKI

该元素包含一个 <KeyInfo> 元素,该元素带有一个 <X509Data> 子元素,而该子元素又包含一个 <X509SKI> 元素。WS-Security 规范不建议将 <Signature> and <EncryptedKey> 元素用于此用途,但可以将其用于 <Assertion> 元素。

$$$KeyInfoX509SubjectName

该元素包含一个 <KeyInfo> 元素,该元素带有一个 <X509Data> 子元素,而该子元素又包含一个 <X509SubjectName> 元素。WS-Security 规范不建议将<Signature> and <EncryptedKey> 元素用作此用途,但可以将其用于<Assertion>元素。

$$$KeyInfoRSAKey

该元素包含一个 <KeyInfo> 元素,该元素带有一个 <KeyValue> 子元素,而该子元素又包含一个 <RSAKeyValue> 元素。WS-Security 规范不建议将 <Signature> and <EncryptedKey> 元素用作此用途,但可以将其用于 <Assertion> 元素。

0
0 103
文章 姚 鑫 · 九月 9, 2024 2m read

第十七章 手动添加安全元素

本主题主要介绍如何手动向 IRIS Web 服务和 IRIS Web 客户端发送的消息中添加安全元素。

以下主题提供了有关特定安全任务的详细信息。

添加安全标头元素

要将安全元素添加到 WS-Security 标头元素,请在 Web 客户端或 Web 服务中使用以下常规过程:

  1. 创建适用类的实例。为此,可以使用名为 Create()CreateX509() 的方法(具体取决于类)。该实例表示 WS-Security 标头元素之一,例如 <Username> or <EncryptedKey>
  2. 通过更新 Web 客户端或 Web 服务的 SecurityOut 属性,将每个实例添加到 WS-Security 标头元素。为此,请调用 AddSecurityElement() 方法。
  3. 发送 SOAP 消息。WS-Security 标头包含在消息中,并包含添加到其中的元素。
  4. 对于后续传出消息:
  • 对于 Web 客户端,SecurityOut 属性保持不变,以便此实例的后续出站消息包含添加的安全标头。如果不希望这样,请将 SecurityOut 属性设置为 null
  • 对于 Web 服务,在第一个出站 SOAP 消息之后,SecurityOut属性会自动设置为null`。

标题元素的顺序

当将多个安全元素添加到标头时,按适当的顺序添加安全标头元素非常重要。当对同一消息元素执行加密和签名时,这一点尤其重要:即按执行加密和签名操作的相同顺序添加它们。

标头元素的顺序指示了消息处理的顺序。WS-Security 1.1 规范规定如下:

当元素添加到 <wsse:Security> 标头块时,它们应该被添加到现有元素的前面。因此,<wsse:Security> 标头块表示消息生产者创建消息所采取的签名和加密步骤。此前置规则确保接收应用程序可以按照子元素在<wsse:Security> 标头块中出现的顺序处理子元素,因为子元素之间不存在前向依赖关系。

当添加标题元素时, IRIS 会将每个元素添加到先前添加的元素之前,但以下情况除外:

  • 如果包含 <Timestamp> 元素,则强制将其作为第一个。
  • 如果包含任何 <BinarySecurityToken> 元素,它们将被强制遵循 <Timestamp> 元素(如果包含)或被强制放在第一个。
  • 当使用 AddSecurityElement() 添加安全标头元素的加密版本时,可以指定第二个参数来强制插入的 <EncryptedData> 元素遵循关联的 <EncryptedKey>

当对同一消息元素执行加密和签名时,按适当的顺序添加安全标头元素尤为重要:即,按照执行加密和签名操作的相同顺序添加它们。

0
0 62
文章 姚 鑫 · 九月 8, 2024 3m read

第二十章 加密 SOAP 主体

本主题介绍如何加密 IRIS Web 服务和 Web 客户端发送的 SOAP 消息正文。

主题“加密安全标头元素”和“使用派生密钥令牌进行加密和签名”描述了如何加密安全标头元素以及加密 SOAP 主体的其他方法。

加密概述

IRISSOAP 消息加密的支持基于 WS-Security1.1。反过来,WS-Security 遵循 XML 加密规范。根据后者规范,要加密 XML 文档:

  1. 生成一个对称密钥以供临时使用。
  2. 可以使用它来加密文档(或文档的选定部分)。

使用包含内容加密版本的 <EncryptedData> 元素替换文档的这些部分。

  1. 使用要向其发送文档的实体的公钥加密对称密钥。

可以从该实体的请求消息中包含的 X.509 证书中获取公钥。或者可以提前获取它。

  1. 在同一文档中的 <EncryptedKey> 元素中包含加密的对称密钥。 <EncryptedKey> 元素直接或间接地提供信息,使接收者能够确定用于解密此元素的密钥。

此信息可以包含在 <EncryptedKey> 元素中,或者 <EncryptedKey> 元素可以包含对包含 X.509 证书或签名的 SAML 断言的二进制安全令牌的直接引用。在后一种情况下,必须在添加 <Signature>元素之前将安全令牌添加到消息中。

文档可以包含多个<EncryptedKey> 元素,适用于文档的不同加密部分。

其他主题介绍了加密 SOAP 消息部分内容的其他方法。消息本身的细节各不相同,但一般过程相同,并遵循 XML 加密规范:生成并使用对称密钥,加密对称密钥,并将加密的对称密钥包含在消息中。

加密 SOAP 主体

要加密 SOAP 消息的正文,可以使用此处的基本过程或小节中描述的变体。首先,下图总结了该过程:

具体过程如下:

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 获取包含将接收 SOAP 消息的实体的公钥的凭证集,通常来自收到的入站消息。请参阅以编程方式检索凭证集。

例如:

 set credset=..SecurityIn.Signature.X509Credentials

请务必检查返回对象的类型,看它是否是 %SYS.X509Credential的实例,如以编程方式检索凭据集中所述。

  1. 创建包含与该凭证集关联的证书的二进制安全令牌。为此,请调用 %SOAP.Security.BinarySecurityTokenCreateX509Token() 类方法。例如:
 set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)

此方法返回代表 <BinarySecurityToken> 标头元素的 %SOAP.Security.BinarySecurityToken实例。

  1. 将此令牌添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于方法参数,请使用您刚刚创建的令牌。例如:
 do ..SecurityOut.AddSecurityElement(bst)
  1. 根据二进制安全令牌创建加密密钥。为此,请调用 %XML.Security.EncryptedKey的 CreateX509() 类方法。例如:
 set enckey=##class(%XML.Security.EncryptedKey).CreateX509(bst)

此方法生成一个对称密钥,使用它来加密 SOAP 主体,并返回 %XML.Security.EncryptedKey 的实例,该实例表示 <EncryptedKey> 标头元素。此标头元素包含对称密钥,由给定二进制安全令牌中包含的公钥加密。

  1. 可选择修改加密密钥实例以使用不同的算法。请参阅指定块加密算法和指定密钥传输算法。
  2. <EncryptedKey> 元素添加到 WS-Security 标头元素。为此,请调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于要添加的元素,请指定 %XML.Security.EncryptedKey 的实例。

例如:

 do ..SecurityOut.AddSecurityElement(enckey)

此步骤还添加 <EncryptedData> 元素作为 <Body> 元素的子元素。

  1. 发送 SOAP 消息。SOAP 主体已加密,并包含 WS-Security 标头。

WS-Security 标头包括<BinarySecurityToken> and <EncryptedKey> 元素。

0
0 119
文章 姚 鑫 · 九月 7, 2024 2m read

第十九章 添加时间戳和用户名令牌 - 时间戳和用户名令牌示例

时间戳和用户名令牌示例

此示例显示了一个需要密码验证的 Web 服务,以及一个在其请求消息中发送时间戳和用户名令牌的 Web 客户端。

注意:此示例以明文形式发送用户名和密码。

为了使此示例在自己的环境中运行,请首先执行以下操作:

  • 对于 Web 服务所属的 Web 应用程序,将该应用程序配置为仅支持密码验证:
  1. 从管理门户主页,选择系统管理 > 安全 > 应用程序 > Web 应用程序。
  2. 选择 Web 应用程序。
  3. 仅选择密码选项,然后选择保存。
  • 如果不使用默认设置,请编辑客户端以使用适当的 IRIS 用户名和密码。

Web服务如下:

Class Tokens.DivideWS Extends %SOAP.WebService
{

Parameter SECURITYIN = "REQUIRE";

///  Name of the Web service.
Parameter SERVICENAME = "TokensDemo";

///  SOAP namespace for the Web service
Parameter NAMESPACE = "http://www.myapp.org";

///  Divide arg1 by arg2 and return the result. In case of error, call ApplicationError.
Method Divide(arg1 As %Numeric = 2, arg2 As %Numeric = 8) As %Numeric [ WebMethod ]
{
  Try {
      Set ans=arg1 / arg2
      }Catch{
      Do ..ApplicationError("division error")
      }
  Quit ans
}

///  Create our own method to produce application specific SOAP faults.
Method ApplicationError(detail As %String)
{
    //details not shown here
}

}

以下客户端类调用代理客户端(此处未显示)并添加用户名令牌:

Include %systemInclude

Class TokensClient.UseClient
{

ClassMethod Test() As %Numeric
{
  Set client=##class(TokensClient.TokensDemoSoap).%New()
  
  Do ..AddSecElements(.client)
  Set ans=client.Divide(1,2)
  
  Quit ans
}

ClassMethod AddSecElements(ByRef client As %SOAP.WebClient)
{
   Set utoken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
   Do client.SecurityOut.AddSecurityElement(utoken)

   Set ts=##class(%SOAP.Security.Timestamp).Create()
   Do client.SecurityOut.AddSecurityElement(ts) 
   Quit
}

}

来自该客户端的示例消息如下:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope [parts omitted]>
  <SOAP-ENV:Header>
   <Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <Timestamp xmlns="[parts omitted]oasis-200401-wss-wssecurity-utility-1.0.xsd">
         <Created>2010-03-12T20:18:03Z</Created>
         <Expires>2010-03-12T20:23:03Z</Expires>
      </Timestamp>
      <UsernameToken>
         <Username>_SYSTEM</Username>
         <Password 
          Type="[parts omitted]#PasswordText">
            SYS
         </Password>
      </UsernameToken>
      </Security>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      [omitted]
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
0
0 87
文章 姚 鑫 · 九月 6, 2024 3m read

第十八章 添加时间戳和用户名令牌

本主题讨论时间戳和用户令牌。

概述

时间戳是 WS-Security 标头中的 <Timestamp> 安全元素。严格来说,时间戳不是安全元素。但是,可以使用它来避免重放攻击。时间戳对于自定义日志记录也很有用。

用户名令牌是 WS-Security 标头中的 <UsernameToken> 安全元素;它带有用户名。它还可以带有相应的密码(可选为摘要形式)。通常使用它进行身份验证,即允许 IRIS Web 客户端使用需要密码的 Web 服务。

注意:默认情况下,WS-Security 标头元素以明文形式发送。要保护 <UsernameToken> 中的密码,应该使用 SSL/TLS、加密 <UsernameToken>(如其他地方所述),或者使用这些技术的某种组合。

添加时间戳

要将时间戳添加到 WS-Security 标头元素,请在 Web 客户端或 Web 服务中执行以下操作:

  1. 调用 %SOAP.Security.Timestamp的 Create() 类方法。此方法需要一个可选参数(以秒为单位的过期间隔)。默认过期间隔为 300 秒。例如:
 set ts=##class(%SOAP.Security.Timestamp).Create()

此方法创建 %SOAP.Security.Timestamp 的实例,设置其 CreatedExpiresTimestampAtEnd 属性的值,并返回该实例。此实例表示 <Timestamp> 标头元素。

  1. 调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于方法参数,请在创建的实例中使用 %SOAP.Security.Timestamp例如:
 do client.SecurityOut.AddSecurityElement(ts)
  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。

如果包含 <Timestamp> 元素,IRIS 会强制它位于 <Security> 中的第一个。

添加用户名令牌

要添加用户名令牌,请在 Web 客户端中执行以下操作:

  1. 可选择包含 %soap.inc 包含文件,它定义了可能需要使用的宏。
  2. 调用 %SOAP.Security.UsernameToken的 Create() 类方法。例如:
 set user="SYSTEM"
 set pwd="_SYS" 
 set utoken=##class(%SOAP.Security.UsernameToken).Create(user,pwd)

该方法具有可选的第三个参数(类型),用于指定如何将密码包含在用户名令牌中。该参数必须是以下之一:

  • $$$SOAPWSPasswordText — 以纯文本形式包含密码。这是默认设置。
  • $$$SOAPWSPasswordDigest — 不包括密码,而是包括其摘要。摘要、Nonce 和创建时间戳均按照 WS-Security 1.1 的规定派生。

重要提示:此选项仅适用于与支持该选项的第三方服务器交互的 SOAP 客户端。PasswordDigest 身份验证要求服务器存储纯文本密码,这在现代安全环境中是不可接受的。PasswordDigest 算法应被视为一项旧功能。要保护 <UsernameToken> 中的密码,应该使用 SSL/TLS、加密 <UsernameToken> 或使用这些技术的某种组合。

  • $$$SOAPWSPasswordNone — 不包括密码。

此方法创建 %SOAP.Security.UsernameToken 的实例,设置其用户名和密码属性,并返回该实例。此对象表示 <UsernameToken> 标头元素。

  1. 调用 Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于方法参数,请在创建的实例中使用 %SOAP.Security.UsernameToken例如:
 do client.SecurityOut.AddSecurityElement(utoken)
  1. 发送 SOAP 消息。请参阅添加安全标头元素中的一般注释。
0
0 139
文章 姚 鑫 · 九月 5, 2024 1m read

第十六章 WS-Policy 配置类详细信息 - 自定义配置示例

自定义配置示例

本节提供了一些自定义配置类的示例。

策略备选配置

以下配置类包括两种策略选择:使用 WS-Addressing 标头或不使用。

/// PolicyAlternatives.DivideWSConfig
Class PolicyAlternatives.DivideWSConfig Extends %SOAP.Configuration
{

XData service
{
<cfg:configuration xmlns:cfg="http://www.intersystems.com/configuration" 
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" 
xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl" 
xmlns:wsp="http://www.w3.org/ns/ws-policy" 
name="service">
  <cfg:service classname="PolicyAlternatives.DivideWS">
   <wsp:Policy>
     <wsp:ExactlyOne>
       <wsp:All>
         <wsap:UsingAddressing/>
       </wsp:All>
       <wsp:All>
         <wsp:Policy/>
       </wsp:All>
     </wsp:ExactlyOne>
    </wsp:Policy>
  </cfg:service>
</cfg:configuration>
}

}

当与附加策略需要 WS-AddressingWeb 客户端一起使用时,此 Web 服务将使用包含 WS-Addressing 标头的消息进行响应。当与策略不使用 WS-Addressing 的客户端一起使用时,此 Web 服务将使用不包含 WS-Addressing 标头的消息进行响应。

另一种情况是,一项策略要求 SSL/TLS,而另一项策略使用消息加密。

带策略参考的配置

以下配置类包含两个 XData 块。一个包含 ID 属性为 mypolicy 的策略。另一个包含 Web 服务的配置;此配置引用另一个 XData 块中包含的策略:

Class DemoPolicies.WithReferenceConfig Extends %SOAP.Configuration
{

XData service
{
<cfg:configuration 
xmlns:cfg="http://www.intersystems.com/configuration"  
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" 
xmlns:wsp="http://www.w3.org/ns/ws-policy" 
name="service">
  <cfg:service classname="DemoPolicies.WithReference">
    <wsp:PolicyReference URI="#mypolicy">
    </wsp:PolicyReference>
  </cfg:service>
</cfg:configuration>
}

XData Policy1
{
<wsp:Policy 
  xmlns:wsp="http://www.w3.org/ns/ws-policy" 
  xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility"
  xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl" 
  xmlns:wsoma="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization" 
  wsu:Id="mypolicy">
 <wsap:UsingAddressing/>
 <wsoma:OptimizedMimeSerialization/>
</wsp:Policy>
}

}

在此示例中,策略表达式包含在名为 Policy1XData 块中。此块的名称对 WSDL 或任何 SOAP 操作均无影响。

0
0 65
文章 姚 鑫 · 九月 4, 2024 3m read

第十五章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(二)

<method>

<method> 元素将策略与父 <service> 元素指定的 Web 服务或客户端内的特定 Web 方法相关联。<method> 元素包括以下项目:

Attribute or ElementPurpose
nameWeb 方法的名称。
<wsp:Policy>(包括 01)指定要应用于此 Web 服务或客户端的策略(在操作级别)。指定 WS-Policy 1.2WS-Policy 1.5 策略表达式。指定<wsp:Policy>, <wsp:PolicyReference>, 或不指定。
<wsp:PolicyReference>(包括 01)为此 Web 方法指定可选的引用 WS-Policy 1.2WS-Policy 1.5 策略表达式。policyID 属性是对同一配置类中不同 XData 块中定义的本地策略的引用。有关示例,请参阅使用 PolicyReference 的配置。指定 <wsp:Policy>, <wsp:PolicyReference> 或两者都不指定。
<request>(包括 01)将策略与 Web 方法的请求消息关联。
<response>(包括 01)将策略与 Web 方法的响应消息关联。

<method><wsp:Policy> or <wsp:PolicyReference> 子元素中,可以指定 cfg:wsdlElement 属性,该属性指定要将此策略元素附加到 WSDL 的哪个部分。在此上下文中,此属性可以具有以下任意值:

  • binding”(默认)— 将此策略元素附加到 WSDL <binding>元素。
  • portType” — 将此策略元素附加到 WSDL <portType>元素。

<request>

<request>元素将策略与父<method>元素引用的 Web 方法的请求消息关联起来。<request>元素包括以下项目:

Attribute or ElementPurpose
<wsp:Policy>(包括 01)指定要应用于请求消息的策略。指定 WS-Policy 1.2WS-Policy 1.5 策略表达式。指定 <wsp:Policy>, <wsp:PolicyReference>或不指定。
<wsp:PolicyReference>包括 01) 为请求消息指定可选的引用 WS-Policy 1.2WS-Policy 1.5 策略表达式。policyID 属性是对同一配置类中不同 XData 块中定义的本地策略的引用。有关示例,请参阅使用 PolicyReference 的配置。指定 <wsp:Policy>, <wsp:PolicyReference> 或两者都不指定。

<request><wsp:Policy> or <wsp:PolicyReference> 子元素中,您可以指定 cfg:wsdlElement 属性,该属性指定要将此策略元素附加到 WSDL 的哪个部分。在此上下文中,此属性可以具有以下任意值:

  • “binding”(默认)— 将此策略元素附加到 WSDL <binding>元素。
  • “portType” — 将此策略元素附加到 WSDL<portType> 元素。
  • “message” — 将此策略元素附加到 WSDL<message> 元素。

<response>

<response> 元素将策略与父 <method> 元素引用的 Web 方法的响应消息关联起来。<response> 元素包括以下项目:.

Attribute or ElementPurpose
<wsp:Policy>(包括 0 或 1)指定要应用于响应消息的策略。指定 WS-Policy 1.2WS-Policy 1.5 策略表达式。指定 <wsp:Policy>, <wsp:PolicyReference>或不指定。
<wsp:PolicyReference>(包括 01)为响应消息指定可选的引用 WS-Policy 1.2WS-Policy 1.5 策略表达式。policyID 属性是对同一配置类中不同 XData 块中定义的本地策略的引用。有关示例,请参阅使用 PolicyReference 的配置。指定 <wsp:Policy>, <wsp:PolicyReference> 或两者都不指定。

<response><wsp:Policy> or <wsp:PolicyReference> 子元素中,可以指定 cfg:wsdlElement 属性,该属性指定要将此策略元素附加到 WSDL 的哪个部分。在此上下文中,此属性可以具有以下任意值:

  • “binding”(默认)— 将此策略元素附加到 WSDL <binding>元素。
  • “portType” — 将此策略元素附加到 WSDL<portType> 元素。
  • “message” — 将此策略元素附加到 WSDL<message> 元素。
0
0 87
文章 姚 鑫 · 九月 3, 2024 2m read

第十四章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(一)

配置 XData 块的详细信息

本节介绍 Web 服务或客户端配置类的 XData 块的内容。

<configuration>, <service>, <method>, <request>, and <response>元素都必须位于以下命名空间中:

"http://www.intersystems.com/configuration"

在本主题中,前缀 cfg 指的是该命名空间。

<configuration>

<configuration> 元素是 XData 块中的根元素。此元素包括以下项目:

Attribute or ElementPurpose
name(可选)此配置的名称。如果指定,则必须与 XData 块的名称匹配。
<service>(可选)将策略与 IRIS Web 服务或 Web 客户端关联。

<service>

<service> 元素将策略与 IRIS Web 服务或 Web 客户端关联。此元素包括以下项目:

Attribute or ElementPurpose
classname(必填) IRIS 网络服务或客户端的完整包和类名。
<wsp:Policy>(包括 01)指定要应用于此 Web 服务或客户端的策略(在绑定级别)。指定 WS-Policy 1.2WS-Policy 1.5 策略表达式。指定 <wsp:Policy>, <wsp:PolicyReference> 或不指定。
<wsp:PolicyReference>(包括 0 1)指定要应用于此 Web 服务或客户端(在绑定级别)的策略引用。如果指定此属性,则 policyID 属性必须是对同一配置类中不同 XData 块中定义的本地策略的引用。有关示例,请参阅使用 PolicyReference 的配置。指定 <wsp:Policy>, <wsp:PolicyReference> 或不指定。
<method>(包括 0 个或多个)将策略与给定 Web 服务或客户端中的特定 Web 方法关联(以在操作级别应用)<service> 元素可以包含任意数量的 <method>元素。

例如:

<cfg:configuration 
xmlns:cfg="http://www.intersystems.com/configuration" 
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" 
xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl" 
xmlns:wsp="http://www.w3.org/ns/ws-policy" 
name="service">
  <cfg:service classname="DemoPolicies.NoSecurity">
    <wsp:Policy>
      <wsap:UsingAddressing/>
    </wsp:Policy>
  </cfg:service>
</cfg:configuration>

<service>, 的 <wsp:Policy> or <wsp:PolicyReference> 子元素中,可以指定 cfg:wsdlElement 属性,该属性指定要将此策略元素附加到 WSDL 的哪个部分。在此上下文中,此属性可以具有以下任意值:

  • “service” — 将此策略元素附加到 WSDL <service>元素。
  • “port” — 将此策略元素附加到 WSDL <port>元素。
  • “binding”(默认)— 将此策略元素附加到 WSDL <binding> 元素。
  • “portType” — 将此策略元素附加到 WSDL <portType> 元素。
0
0 78
文章 姚 鑫 · 九月 2, 2024 1m read

第十三章 WS-Policy 配置类详细信息 - 添加扩展属性

添加扩展属性

除了 cfg:wsdlElement 属性(前面讨论过)之外,可能还需要在策略元素中的以下元素中添加扩展属性:

  • <sp:X509Token> (在 <sp:InitiatorToken> or <sp:RecipientToken> 内)

    在此元素中,为 cfg:FindFieldcfg:FindValue 属性指定一个值,这些值指定用于此令牌的 IRIS 凭证集。

    • cfg:FindField 属性指定要搜索的字段的名称。通常为 Alias
    • cfg:FindValue 属性指定该字段的值。如果 cfg:FindFieldAlias,则这是 IRIS 凭证集的名称。

例如:

<sp:X509Token IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never" 
              cfg:FindField="Alias" 
              cfg:FindValue="servercred">
  <wsp:Policy>
    <sp:WssX509V3Token11/>
  </wsp:Policy>
</sp:X509Token>
  • <sp:HttpsToken>

在此元素中,为 cfg:SSLConfiguration 属性指定一个值。这应该等于 IRIS SSL/TLS 配置的名称。例如:

<sp:HttpsToken cfg:SSLConfiguration="mysslconfig">
    <wsp:Policy/>
</sp:HttpsToken>

仅为 Web 客户端指定此属性。

  • <sp:SecureConversationToken>

在此元素中,可以指定 cfg:Lifetime 属性。这应该等于安全对话的生存期,以小时或小时的小数部分为单位。默认生存期为 5 分钟。假设我们想指定生存期为 15 分钟。为此,我们编辑 <sp"SecureConversationToken>,如下所示。

<sp:SecureConversationToken cfg:Lifetime=".25"
  sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
    <wsp:Policy>
      <sp:MustNotSendAmend/>
      <sp:MustNotSendRenew/>
  ...
  </wsp:Policy>
</sp:SecureConversationToken>

仅为 Web 客户端指定此属性。

如果在生成 Web 客户端或服务时生成配置类,则可能需要编辑这些属性。

0
0 69
文章 姚 鑫 · 九月 1, 2024 1m read

第十二章 WS-Policy 配置类详细信息 - 配置类基础知识

作为参考,本主题包含有关 IRIS 用于存储 WS-Policy 信息的配置类的详细信息。

配置类基础知识

要手动创建 WS-Policy 配置类,请创建 %SOAP.Configuration 的子类。在此类中,添加 XData 块,如下所示:

XData service
{
<cfg:configuration xmlns:cfg="http://www.intersystems.com/configuration" name="service">
...

XData 块具有以下一般结构:

XData service
{
<cfg:configuration ...>
   <service ...>
      <method ...>
         <request ...>
         <response ...>
...

<service>, <method>, <request>, and <response> 元素均可包含适用于该级别的策略信息。<service> 元素是必需的,但其他元素是可选的。

如果包含策略信息,则该信息要么是策略表达式(即 <wsp:Policy> 元素),要么是策略引用(即指向同一配置类中另一个 XData 块中包含的策略的 <wsp:PolicyReference> 元素)。以下部分提供了更多详细信息。

请注意, <PolicyReference> 仅在两个位置受支持:代替配置元素内的 <Policy> 元素或作为<Policy> 元素的唯一子元素。

0
0 95
文章 姚 鑫 · 八月 29, 2024 2m read

第十一章 创建和使用策略 - 在运行时指定策略

在运行时指定策略

对于 IRIS Web 客户端,可以指定运行时要使用的策略;这将覆盖任何策略配置类。要在运行时指定策略,请设置 Web 客户端实例的 PolicyConfiguration 属性。该值必须具有以下形式:

Configuration class name:Configuration name

其中,配置类名称是策略配置类的完整包和类名,如本主题前面所述,配置名称是该类中策略的 <configuration> 元素的 name 属性的值

抑制不支持的策略的编译错误

默认情况下,当编译配置类时,如果配置包含 IRIS 不支持的任何策略表达式, IRIS 会发出错误。要避免此类错误,请在配置类中包含以下内容:

Parameter REPORTANYERROR=0;

当从 WSDL 生成 Web 客户端或 Web 服务时,如果 IRIS 还生成配置类,则会将此参数设置包含在该类中。

只要有一个受支持的策略替代方案,就可以忽略不受支持的替代方案。

编辑生成的策略

如果从 WSDL 生成配置类,并且 WSDL 位于 IRIS 此实例的外部,则必须编辑配置类以包含有关要使用的证书和 SSL/TLS 配置的信息。或者可以在运行时指定此信息。

下表给出了详细信息:

If the Generated Policy Includes ...Do the following ...
<sp:HttpsToken>对于附加到客户端的策略,请执行以下操作之一:
按照添加扩展属性中的说明编辑此元素。
按照指定客户端要使用的 SSL/TLS 配置中所述指定 SSL/TLS 配置的名称。
对于附加到服务的策略,不需要进行任何更改。
<sp:InitiatorToken>对于附加到客户端的策略,请执行以下操作之一:
按照添加 InterSystems 扩展属性中所述编辑其中的 <sp:X509Token>元素。
检索凭证集并添加包含的证书,如在运行时添加证书中所述。
无论如何,这必须是客户端拥有的凭证集。对于附加到服务的策略,无需进行任何更改。
<sp:RecipientToken>执行以下操作之一:
按照添加 扩展属性中所述编辑其中的 <sp:X509Token>元素。
检索凭证集并添加包含的证书,如在运行时添加证书中所述。
无论哪种情况,这都必须是服务拥有的凭证集。
<sp:SecureConversationToken>可选择添加 cfg:Lifetime 属性,如添加 扩展属性中所述。默认生存期为 5 分钟。
0
0 51
文章 姚 鑫 · 八月 28, 2024 2m read

第十章 创建和使用策略 - 在运行时添加证书

在运行时添加证书

如果 Web 服务或客户端必须以编程方式选择并包含证书,请使用以下过程:

  1. 检索 %SYS.X509Credentials 的实例,如以编程方式检索凭据集中所述。

例如:

 set credset=##class(%SYS.X509Credentials).GetByAlias(alias,password)

 set credset=..SecurityIn.Signature.X509Credentials 
  1. 创建 %SOAP.Security.BinarySecurityToken 实例,其中包含来自该凭证集的证书。例如:
 set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)

其中 credentials 是在上一步中检索到的凭证集。

这将返回一个代表 <BinarySecurityToken> 元素的对象,该元素以序列化的 base-64 编码形式携带证书。

  1. 调用Web 客户端或 Web 服务的 SecurityOut 属性的 AddSecurityElement() 方法。对于方法参数,请使用之前创建的二进制安全令牌。例如:
 do ..SecurityOut.AddSecurityElement(bst)

重要提示:在某些情况下,需要两个二进制安全令牌:一个用于加密,一个用于签名。请确保按适当的顺序添加它们。如果策略先加密消息然后对其进行签名,请确保先添加用于加密的二进制安全令牌,然后再添加用于签名的令牌。相反,如果策略先签名然后加密,则第一个二进制安全令牌必须是用于签名的令牌。

下面显示了 Web 服务中的 Web 方法的示例:

 //get credentials
 set x509alias = "something"
 set pwd = "password"
 set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,pwd)

 //get certificate and add it as binary security token
 set cert = ##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
 do ..SecurityOut.AddSecurityElement(cert)

对于 Web 客户端,代码会略有不同,因为通常不会编辑代理客户端:

 set client=##class(proxyclient.classname).%New()
 //get credentials
 set x509alias = "something"
 set pwd = "password"
 set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,pwd)

 //get certificate and add it as binary security token
 set cert = ##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
 do client.SecurityOut.AddSecurityElement(cert)
 //invoke web method of client
0
0 81
文章 姚 鑫 · 八月 28, 2024 2m read

第九章 创建和使用策略 - 创建并附加策略

创建并附加策略

要创建策略并将其附加到Web 服务或客户端,请创建并编译配置类。有多种方法可以创建此类:

  • 使用 GeneratePolicyFromWSDL() 方法从 WSDL 生成配置类。如果 Web 服务或客户端类已存在,并且您不想重新生成,则适用此选项。
  • 为现有的 Web 服务或客户端手动创建配置类。

如果从 WSDL 生成策略类,则可能需要按下一节所述对其进行编辑。

WSDL 生成策略

在某些情况下,可能已经有客户端类,但没有相应的配置类。例如,如果从 WSDL 生成客户端类,而 WSDL 后来被修改为包含 WS-Policy 信息,则可能会发生这种情况。在这种情况下,可以使用 %SOAP.WSDL.Reader中的实用程序方法单独生成配置类,如下所示:

  1. 创建 %SOAP.WSDL.Reader 的实例。
  2. 根据需要设置该实例的属性。请参阅 %SOAP.WSDL.Reader 类文档。

不要使用 Process() 方法。

  1. 调用实例的 GeneratePolicyFromWSDL() 方法。

此方法具有以下签名:

method GeneratePolicyFromWSDL(wsdlURL As %String, 
    clientWebServiceClass As %String, 
    policyConfigClass As %String) as %Status

其中:

  • wsdlURL 是包含策略的 WSDLURL。假设 WSDL 仅指定一个端口。
  • clientWebServiceClassWeb 客户端类的名称。有责任确保此 Web 客户端与给定的 WSDL 匹配。
  • policyConfigClass 是要创建的配置类的名称。

这将为 Web 服务客户端创建(或覆盖)一个配置类,其中包含 Web 服务的 WSDL 指定的策略。如果 WSDL 中没有策略,则创建一个空的配置类。如果实例的 CompileClasses 属性等于 1,则将编译该配置类。

0
0 101
文章 姚 鑫 · 八月 26, 2024 3m read

第八章 创建和使用策略

本主题介绍如何在 IRIS 中使用 WS-Policy 支持。WS-Policy 使您能够指定要使用或预期的 WS-Security 标头。它还使能够指定 WS-Addressing 标头和 MTOM 的使用(在创建 Web 服务和 Web 客户端中描述)。可以在单独的类中创建策略,而不是直接编辑 Web 服务或 Web 客户端。在大多数情况下,不需要进行低级编程。

概述

IRIS 中,Web 服务或客户端的策略(或策略集合)包含在单独的配置类中,即 %SOAP.Configuration的子类。编译该类时,策略生效。

通常不需要编码。但是,在某些情况下,可以通过编程指定详细信息,而不是将该元素硬编码到策略中。

配置类的作用

当编译配置类时,Web 服务或客户端的未来操作将受到如下影响:

  • Web 服务或客户端根据策略的详细信息在出站消息中包含额外的标头元素。
  • Web 服务或客户端根据策略验证传入的 SOAP 消息。这包括在适当的情况下解密传入的消息。
  • 如果合适,Web 服务或客户端可以选择加密传出消息。
  • 对于 Web 服务,WSDL 会自动受到影响。具体来说,会添加 <wsp:Policy> 元素,并且命名空间声明包括以下内容:
xmlns:wsp="http://www.w3.org/ns/ws-policy"

重要提示:如果配置类映射到多个命名空间,则必须在每个命名空间中对其进行编译。

WS-SecurityWS-AddressingMTOM 支持的关系

IRISWS-Policy 的支持建立在 IRISWS-SecurityWS-AddressingMTOM 的支持之上。请注意以下几点:

  • 如果策略不包含安全策略, IRIS 将使用 Web 服务或 Web 客户端的 SecurityOut 属性。(要手动将安全标头元素添加到 Web 服务或客户端,请将它们添加到 SecurityOut 属性,如其他地方所述。)
  • 如果策略确实包含安全策略,IRIS 将忽略 Web 服务或 Web 客户端的 SecurityOut 属性,但与该策略相关的任何元素除外。

例如,当使用相互 X.509 证书安全策略时,可以指定一个 IRIS 凭证集以直接在策略中使用,或者您可以在创建 %SYS.X509Credentials 的实例,并将其包含在二进制安全令牌中添加到 SecurityOut 属性。如果没有在策略中直接指定凭证集,IRIS 将从 SecurityOut 属性中检索二进制安全令牌并使用它。但是 IRIS 会忽略 SecurityOut 属性中的其他元素,因为它们不适用于此场景。

  • 如果策略需要 WS-AddressingIRIS 将忽略 WSADDRESSING 类参数。

但是,如果设置了 AddressingOut 属性,IRIS 将使用它指定的 WS-Addressing 标头。否则,它将使用默认的 WS-Addressing 标头集。

  • 如果策略需要 MTOMIRIS 将忽略 MTOMREQUIRED 类参数和 MTOMRequired 属性。

Web 服务和 Web 客户端的关系

当将策略附加到 Web 服务时,所有客户端都必须能够遵守该策略。如果 Web 服务策略不包含任何策略替代方案,则客户端必须具有与 Web 服务相同的策略,并在需要时用客户端证书代替服务器端证书。

类似地,如果将策略附加到 Web 客户端,则服务必须能够遵守该策略。

实际操作中,如果服务和客户端都是在 IRIS 中创建的,则以下步骤是最简单的:

  1. 创建 Web 服务类。
  2. 使用服务策略创建 Web 服务配置类。
  3. 生成客户端类,包括客户端配置类。

完成此操作后,检查生成的客户端类并根据需要进行更改。

通常还会为其创建一个包装类。

  1. 检查生成的配置类并根据需要进行更改。
0
0 75
文章 姚 鑫 · 八月 25, 2024 2m read

第七章 设置和其他常见活动 - 从入站消息中检索证书

从入站消息中检索证书

如果收到已进行数字签名的 SOAP 消息,则相关证书可在 %SYS.X509Credentials 的实例中找到。可以检索该证书。操作方法如下:

  1. 首先通过 Web 服务或 Web 客户端的 SecurityIn 属性访问 WS-Security 标头元素。这将返回 %SOAP.Security.Header 的实例。
  2. 然后执行以下操作之一:
  • 在实例中访问 %SOAP.Security.HeaderSignature 属性,该属性引用安全标头元素中的第一个 <Signature> 元素。
  • 在实例中使用 %SOAP.Security.HeaderFindElement() 方法访问实例中 %SOAP.Security.Header的第一个 <Signature> 元素。

无论哪种情况,结果都是在包含数字签名的 %XML.Security.Signature 实例。

  1. 访问签名对象的 X509Credentials 属性。
  2. 检查返回对象的类型,看它是否是 %SYS.X509Credentials 的实例。
 if $CLASSNAME(credset)'="%SYS.X509Credentials" {set credset=""}

如果入站消息包含已签名的 SAML 断言,则 X509Credentials 属性是某个其他类的实例,不能用于访问实例中的 %SYS.X509Credentials

示例:

 set credset=..SecurityIn.Signature.X509Credentials 
 if $CLASSNAME(credset)'="%SYS.X509Credentials" {set credset=""}
 //if credset is not null, then use it...

指定客户端要使用的 SSL/TLS 配置

如果 Web 服务需要使用 HTTP over SSL/TLS(HTTPS),则 Web 客户端必须使用适当的 IRIS SSL/TLS 配置。

当手动创建 WS-Security 标头时,必须以编程方式指定要使用的配置。

要指定要使用的 SSL/TLS 配置,请将 Web 客户端的 SSLConfiguration 属性设置为 SSL/TLS 配置名称。例如:

 set client=##class(proxyclient.classname).%New()
 set client.SSLConfiguration="mysslconfig"
 //invoke web method of client

请注意,如果客户端通过代理服务器连接,还必须在 Web 客户端中将 HttpProxySSLConnect 属性设置为 1

0
0 81