Sample code for 30+ languages & platforms
Objective-C

Sign with BinarySecurityToken

See more XML Digital Signatures Examples

Demonstrates creating an XML signature using a BinarySecurityToken.

Chilkat Objective-C Downloads

Objective-C
#import <CkoCert.h>
#import <CkoXml.h>
#import <CkoDateTime.h>
#import <CkoBinData.h>
#import <CkoXmlDSigGen.h>
#import <CkoStringBuilder.h>

BOOL success = NO;

//  This example requires the Chilkat API to have been previously unlocked.
//  See Global Unlock Sample for sample code.

//  -------------------------------------------------------------------------
//  Load a cert + private key from a PFX.
CkoCert *cert = [[CkoCert alloc] init];
success = [cert LoadPfxFile: @"qa_data/pfx/cert_test123.pfx" password: @"test123"];
if (success != YES) {
    NSLog(@"%@",cert.LastErrorText);
    return;
}

//  -------------------------------------------------------------------------
//  Create the XML that is to be signed.
//  
//  The XML we're creating can be found at Sample Pre-Signed XML with BinarySecurityToken
//  The online tool at http://tools.chilkat.io/xmlCreate.cshtml can be used to generate the following XML creation code.
//  

CkoXml *xml = [[CkoXml alloc] init];
xml.Tag = @"S:Envelope";
[xml AddAttribute: @"xmlns:S" value: @"http://www.w3.org/2003/05/soap-envelope"];
[xml AddAttribute: @"xmlns:wsse11" value: @"http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"];
[xml AddAttribute: @"xmlns:wsse" value: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"];
[xml AddAttribute: @"xmlns:wsu" value: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"];
[xml AddAttribute: @"xmlns:xs" value: @"http://www.w3.org/2001/XMLSchema"];
[xml AddAttribute: @"xmlns:ds" value: @"http://www.w3.org/2000/09/xmldsig#"];
[xml AddAttribute: @"xmlns:exc14n" value: @"http://www.w3.org/2001/10/xml-exc-c14n#"];
[xml UpdateAttrAt: @"S:Header|To" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateAttrAt: @"S:Header|To" autoCreate: YES attrName: @"wsu:Id" attrValue: @"_5002"];
[xml UpdateChildContent: @"S:Header|To" value: @"https://XXXXXXXXX"];
[xml UpdateAttrAt: @"S:Header|Action" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateAttrAt: @"S:Header|Action" autoCreate: YES attrName: @"xmlns:S" attrValue: @"http://www.w3.org/2003/05/soap-envelope"];
[xml UpdateAttrAt: @"S:Header|Action" autoCreate: YES attrName: @"S:mustUnderstand" attrValue: @"true"];
[xml UpdateChildContent: @"S:Header|Action" value: @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"];
[xml UpdateAttrAt: @"S:Header|ReplyTo" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateChildContent: @"S:Header|ReplyTo|Address" value: @"http://www.w3.org/2005/08/addressing/anonymous"];
[xml UpdateAttrAt: @"S:Header|FaultTo" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateChildContent: @"S:Header|FaultTo|Address" value: @"http://www.w3.org/2005/08/addressing/anonymous"];
[xml UpdateAttrAt: @"S:Header|MessageID" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateChildContent: @"S:Header|MessageID" value: @"uuid:e9033251-4ff0-4618-8baf-4952ab5fd207"];
[xml UpdateAttrAt: @"S:Header|wsse:Security" autoCreate: YES attrName: @"S:mustUnderstand" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsu:Timestamp" autoCreate: YES attrName: @"xmlns:ns17" attrValue: @"http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsu:Timestamp" autoCreate: YES attrName: @"xmlns:ns16" attrValue: @"http://schemas.xmlsoap.org/soap/envelope/"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsu:Timestamp" autoCreate: YES attrName: @"wsu:Id" attrValue: @"_1"];

//  Get the current date/time in timestamp format, such as "2018-05-23T02:38:27Z"
CkoDateTime *dt = [[CkoDateTime alloc] init];
[dt SetFromCurrentSystemTime];
[xml UpdateChildContent: @"S:Header|wsse:Security|wsu:Timestamp|wsu:Created" value: [dt GetAsTimestamp: NO]];
//  Add 5 minutes.
[dt AddSeconds: [NSNumber numberWithInt: 300]];
[xml UpdateChildContent: @"S:Header|wsse:Security|wsu:Timestamp|wsu:Expires" value: [dt GetAsTimestamp: NO]];

[xml UpdateAttrAt: @"S:Header|wsse:Security|wsse:BinarySecurityToken" autoCreate: YES attrName: @"xmlns:ns17" attrValue: @"http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsse:BinarySecurityToken" autoCreate: YES attrName: @"xmlns:ns16" attrValue: @"http://schemas.xmlsoap.org/soap/envelope/"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsse:BinarySecurityToken" autoCreate: YES attrName: @"ValueType" attrValue: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsse:BinarySecurityToken" autoCreate: YES attrName: @"EncodingType" attrValue: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"];
[xml UpdateAttrAt: @"S:Header|wsse:Security|wsse:BinarySecurityToken" autoCreate: YES attrName: @"wsu:Id" attrValue: @"uuid_43470044-78b4-4b23-926a-b7f590d24cb8"];

CkoBinData *bdCert = [[CkoBinData alloc] init];
[cert ExportCertDerBd: bdCert];

//  Get the cert as base64 on one line.
[xml UpdateChildContent: @"S:Header|wsse:Security|wsse:BinarySecurityToken" value: [bdCert GetEncoded: @"base64"]];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken" autoCreate: YES attrName: @"xmlns" attrValue: @"http://docs.oasis-open.org/ws-sx/ws-trust/200512"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|RequestType" value: @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|wsp:AppliesTo" autoCreate: YES attrName: @"xmlns:wsp" attrValue: @"http://schemas.xmlsoap.org/ws/2004/09/policy"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|wsp:AppliesTo|EndpointReference:EndpointReference" autoCreate: YES attrName: @"xmlns:EndpointReference" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|wsp:AppliesTo|EndpointReference:EndpointReference" autoCreate: YES attrName: @"xmlns" attrValue: @"http://www.w3.org/2005/08/addressing"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|wsp:AppliesTo|EndpointReference:EndpointReference|Address" value: @"https://XXXXXXXXX/services"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|TokenType" value: @"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims" autoCreate: YES attrName: @"xmlns:i" attrValue: @"http://schemas.xmlsoap.org/ws/2005/05/identity"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims" autoCreate: YES attrName: @"Dialect" attrValue: @"http://schemas.xmlsoap.org/ws/2005/05/identity"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType" autoCreate: YES attrName: @"Optional" attrValue: @"false"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/abn"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[1]" autoCreate: YES attrName: @"Optional" attrValue: @"false"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[1]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/commonname"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[2]" autoCreate: YES attrName: @"Optional" attrValue: @"false"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[2]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/credentialtype"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[3]" autoCreate: YES attrName: @"Optional" attrValue: @"false"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[3]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/samlsubjectid"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[4]" autoCreate: YES attrName: @"Optional" attrValue: @"false"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[4]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/fingerprint"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[5]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[5]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/sbr_personid"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[6]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[6]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/givennames"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[7]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[7]" autoCreate: YES attrName: @"Uri" attrValue: @"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[8]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[8]" autoCreate: YES attrName: @"Uri" attrValue: @"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[9]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[9]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/credentialadministrator"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[10]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[10]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/stalecrlminutes"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[11]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[11]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/subjectdn"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[12]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[12]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/issuerdn"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[13]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[13]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/notafterdate"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[14]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[14]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/certificateserialnumber"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[15]" autoCreate: YES attrName: @"Optional" attrValue: @"true"];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Claims|i:ClaimType[15]" autoCreate: YES attrName: @"Uri" attrValue: @"http://XXXXXXXXX/2008/06/identity/claims/previoussubject"];

[dt SetFromCurrentSystemTime];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Lifetime|wsu:Created" autoCreate: YES attrName: @"xmlns:wsu" attrValue: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|Lifetime|wsu:Created" value: [dt GetAsTimestamp: NO]];

//  Add 40 minutes.
[dt AddSeconds: [NSNumber numberWithInt: 2400]];
[xml UpdateAttrAt: @"S:Body|RequestSecurityToken|Lifetime|wsu:Expires" autoCreate: YES attrName: @"xmlns:wsu" attrValue: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|Lifetime|wsu:Expires" value: [dt GetAsTimestamp: NO]];

[xml UpdateChildContent: @"S:Body|RequestSecurityToken|KeyType" value: @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey"];
[xml UpdateChildContent: @"S:Body|RequestSecurityToken|KeySize" value: @"512"];

//  Examine the pre-signed XML
//  println xml.GetXml();

//  Build the custom KeyInfo XML we'll use:
//  
//  	    <wsse:SecurityTokenReference>
//  	        <wsse:Reference URI="#uuid_43470044-78b4-4b23-926a-b7f590d24cb8" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" /></wsse:SecurityTokenReference>

CkoXml *keyInfoXml = [[CkoXml alloc] init];
keyInfoXml.Tag = @"wsse:SecurityTokenReference";
[keyInfoXml UpdateAttrAt: @"wsse:Reference" autoCreate: YES attrName: @"URI" attrValue: @"#uuid_43470044-78b4-4b23-926a-b7f590d24cb8"];
[keyInfoXml UpdateAttrAt: @"wsse:Reference" autoCreate: YES attrName: @"ValueType" attrValue: @"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"];

//  -------------------------------------------------------------------------
//  Setup the XML Digital Signature Generator and add the XML Signature.
//  
CkoXmlDSigGen *gen = [[CkoXmlDSigGen alloc] init];
gen.SigLocation = @"S:Envelope|S:Header|wsse:Security";
gen.SignedInfoPrefixList = @"wsse S";

[gen AddSameDocRef: @"_1" digestMethod: @"sha1" canonMethod: @"EXCL_C14N" prefixList: @"wsu wsse S" refType: @""];
[gen AddSameDocRef: @"_5002" digestMethod: @"sha1" canonMethod: @"EXCL_C14N" prefixList: @"S" refType: @""];

gen.KeyInfoType = @"Custom";
keyInfoXml.EmitXmlDecl = NO;
gen.CustomKeyInfoXml = [keyInfoXml GetXml];

//  Specify the cert for signing (which has a private key because it was loaded from a PFX)
[gen SetX509Cert: cert usePrivateKey: YES];

//  Indicated we want an indented signature for easier human reading.
gen.Behaviors = @"IndentedSignature";

//  Sign the XML..
CkoStringBuilder *sbXml = [[CkoStringBuilder alloc] init];
[xml GetXmlSb: sbXml];

success = [gen CreateXmlDSigSb: sbXml];
if (success != YES) {
    NSLog(@"%@",gen.LastErrorText);
    return;
}

//  Examine the signed XML
NSLog(@"%@",[sbXml GetAsString]);

//  The resulting signature (extracted from the surrounding XML) looks something like this:

//  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
//      <ds:SignedInfo>
//          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
//              <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse S" />
//          </ds:CanonicalizationMethod>
//          <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
//          <ds:Reference URI="#_1">
//              <ds:Transforms>
//                  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
//                      <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsu wsse S" />
//                  </ds:Transform>
//              </ds:Transforms>
//              <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
//              <ds:DigestValue>VAJMC/L/BDvml7Qv5CBMePbKDE8=</ds:DigestValue>
//          </ds:Reference>
//          <ds:Reference URI="#_5002">
//              <ds:Transforms>
//                  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
//                      <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="S" />
//                  </ds:Transform>
//              </ds:Transforms>
//              <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
//              <ds:DigestValue>sW/QFsk6kGv1dzeu0H9Qc/2kvAQ=</ds:DigestValue>
//          </ds:Reference>
//      </ds:SignedInfo>
//      <ds:SignatureValue>....</ds:SignatureValue>
//      <ds:KeyInfo>
//          <wsse:SecurityTokenReference>
//              <wsse:Reference URI="#uuid_43470044-78b4-4b23-926a-b7f590d24cb8" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
//          </wsse:SecurityTokenReference>
//      </ds:KeyInfo>
//  </ds:Signature>
//