Skip to main content

Using a <DerivedKeyToken> for Encryption

Using a <DerivedKeyToken> for Encryption

To use a <DerivedKeyToken> for encryption, use the following procedure:

  1. If you want to encrypt one or more security header elements, create those security header elements.

  2. Create the <DerivedKeyToken> and add it to the WS-Security header, as described in Creating and Adding a <DerivedKeyToken.

    Note that this step also creates and adds the <EncryptedKey> element on which the <DerivedKeyToken> is based.

  3. For each element that you want to encrypt, create an <EncryptedData> element based on the element. To do so, call the Create() class method of %XML.Security.EncryptedDataOpens in a new tab. In this procedure, specify the following arguments:

    1. The derived key token.

    2. The item to encrypt. Omit this argument to encrypt the body.

    3. A macro that specifies how the <EncryptedData> element refers to the <DerivedKeyToken>. In this scenario, the only currently supported value is $$$SOAPWSReferenceDerivedKey.

    For example, to encrypt the <UsernameToken>:

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

    Or, to encrypt the body:

     set refopt=$$$SOAPWSReferenceDerivedKey
     set encryptedData=##class(%XML.Security.EncryptedData).Create(dkenc,,refopt) 
  4. Create a <ReferenceList> element. To do so, call the %New() method of the %XML.Security.ReferenceListOpens in a new tab class. For example:

     set reflist=##class(%XML.Security.ReferenceList).%New() 
  5. Within this <ReferenceList>, create a <ReferenceList> that points to the <EncryptedData> elements. To do so, do the following for each <EncryptedData>:

    1. Call the Create() class method of %XML.Security.DataReferenceOpens in a new tab and specify the encrypted data instance as the argument. This method returns an instance of %XML.Security.DataReferenceOpens in a new tab.

    2. Call the AddReference() method of your reference list instance and specify the data reference instance as the argument.

    For example:

     set dataref=##class(%XML.Security.DataReference).Create(encdata)
     do reflist.AddReference(dataref)
     set dataref2=##class(%XML.Security.DataReference).Create(encdata2)
     do reflist.AddReference(dataref2)
  6. Add the <ReferenceList> element to the WS-Security header element. To do so, call the AddSecurityElement() method of the SecurityOut property of your web client or web service. For the element to add, specify your reference list instance.

    For example:

     do ..SecurityOut.AddSecurityElement(reflist)
  7. If you encrypted any security header elements, add them to the WS-Security header element. To do so, call the AddSecurityElement() method of the SecurityOut property of your web client or web service. In this case, two arguments are required:

    1. The security header element (not the %XML.Security.EncryptedDataOpens in a new tab that you generated from it).

    2. The reference list instance. The second argument specifies where to place the item specified by the first argument. If the arguments are A,B, then InterSystems IRIS ensures that A is after B. You specify this so that the recipient processes the reference list first and later processes the encrypted security header element that depends on it.

    For example:

     do client.SecurityOut.AddSecurityElement(userToken,reflist)

    If you encrypted only the SOAP body, the system automatically includes an <EncryptedData> element as the child of <Body>.

  8. Send the SOAP message. See the general comments in Adding Security Header Elements.

For example, the following client-side code encrypts both the SOAP body and the <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

The client sends messages like the following:

<?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>

For another example, the following web service receives an <EncryptedKey> in the inbound message and uses it to generate a <DerivedKeyToken> that it uses to encrypt parts of the response:

  // 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)

This web service sends messages like the following:

<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>
FeedbackOpens in a new tab