XML signing in Mac Os using swift

I want to sign xml file using enveloped signature approach in swift. The example original xml file could be like below

<?xml version="1.0" encoding="ISO-8859-1"?>
<Envelope xmlns="http://example.org/envelope">
  <Body>
    Olá mundo
  </Body>
</Envelope>

After signature, the xml file would be like this

<?xml version="1.0" encoding="ISO-8859-1"?>
<Envelope xmlns="http://example.org/envelope">
  <Body>
    Olá mundo
  </Body>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>????</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>????</SignatureValue>
    <KeyInfo>
      <KeyValue>
        <RSAKeyValue>????</RSAKeyValue>
      </KeyValue>
    </KeyInfo>
  </Signature>
</Envelope>

Here the steps are

  1. encrypt using sha1WithRSAEncryption signature algorithm (rsa-sha1), which uses the SHA-1 message digest algorithm and RSA PKCS#1v1.5 to create the signature.
  2. Get the digest value using SHA-1
  3. Canonicalization will be according to Canonical XML Version 1.0 or c14n rules.

Is there any library in swift or objective c which i can use for this purpose? I am currently using AEXML to parse, read and write xml file. But for canonical conversion and other steps stated above which library i can use?

For Your reference in C#, Cryptography.Xml provides all those functionalities. The below code in C# do the signing part of XML.

SignedXml signedXml = new SignedXml(xmlDocument);
signedXml.SigningKey = certificate.PrivateKey;

Reference reference = new Reference();

reference.Uri = ""; //"#" + procedureSerial;
reference.Type = reason;
reference.Id = DateTime.UtcNow.Ticks.ToString();

// Add an enveloped transformation to the reference.            
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(true);
reference.AddTransform(env);

// Add the reference to the SignedXml object.
signedXml.AddReference(reference);

//canonicalize
XmlDsigC14NTransform c14t = new XmlDsigC14NTransform();
reference.AddTransform(c14t);

KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate);
KeyInfoName kin = new KeyInfoName();
kin.Value = certificate.FriendlyName;

RSA rsa = (RSA)certificate.PublicKey.Key;
RSAKeyValue rkv = new RSAKeyValue(rsa);
keyInfo.AddClause(rkv);

keyInfo.AddClause(kin);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;

// Compute the signature.
signedXml.ComputeSignature();

// Get the XML representation of the signature and save 
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();

xmlDocument.DocumentElement.AppendChild(
        xmlDocument.ImportNode(xmlDigitalSignature, true)
    );

I want to do same functionalities using swift or objective C to sign xml file in MacOS. Could you please suggest any library regarding this?

In Swift, you can use the Security framework to perform XML digital signing with RSA. Here are the steps to sign an XML file using the enveloped signature approach in Swift:

  1. Import the necessary frameworks:
import Foundation
import Security
import SecurityFoundation
import SwiftXML
  1. Load your XML content from a file or create it programmatically.

  2. Compute the digest value using SHA-1:

func computeDigestValue(data: Data) -> String {
    var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
    data.withUnsafeBytes {
        _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)
    }
    return Data(digest).base64EncodedString()
}
  1. Create a SignedXMLDocument and add the digest value:
let xmlDocument = try XMLDocument(data: yourXMLData)
let signedXMLDocument = SignedXMLDocument(xmlDocument: xmlDocument)

let digestValue = computeDigestValue(data: yourXMLData)
try signedXMLDocument.addDigestValue(id: "", algorithm: "http://www.w3.org/2000/09/xmldsig#sha1", value: digestValue)
  1. Add the signature to the XML document:
let privateKey = yourPrivateKey // Load your RSA private key here
try signedXMLDocument.signWithRSA(privateKey: privateKey)
  1. Save the signed XML document:
let signedXMLData = try signedXMLDocument.xmlData(prettyPrinted: true)
try signedXMLData.write(to: signedXMLFileURL)

This code should help you sign an XML file using the enveloped signature approach in Swift. You would need to replace yourXMLData with the XML data you want to sign and provide your RSA private key. You can use the Security framework to work with RSA keys in Swift.

Please note that handling cryptographic operations like this can be complex, and you should ensure that your private key is securely managed. Additionally, consider using more secure hashing algorithms than SHA-1 for stronger security.

Is there any library in swift or objective c which i can use for this purpose?

There is no high-level API for XML Signature but I believe you can do this by combining two APIs:

  • libxml2 can canonicalise XML (step 3).

  • Security framework can do the necessary crypto (steps 1 and 2).

With regards libxml2, that’s an open source thing so Apple doesn’t publish its own documentation for it. You can find docs on the project website:

http://xmlsoft.org/

On the Security framework side of this, getting all the ducks to line up can be a bit tricky. If you post an example document that includes real values for DigestValue, SignatureValue, and RSAKeyValue, I should be able to give you some guidance. Post a hex dump rather than XML to avoid it being munged by DevForums. Or upload it somewhere and post the URL [1].

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Do this ‘in the clear’ as I’ve shown above. See Quinn’s Top Ten DevForums Tips for more about that.

XML signing in Mac Os using swift
 
 
Q