Digital Signature validation in iOS

I have to validate a digital signature embedded in an XML file. The signature has been generated using RSA 2048 bit document signer key. The file has the Signature as below:


<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>Cppv05Vz3hVEr+UiArSn6aDkGcrF4edvuvY1diDU7Uc=</DigestValue></Reference></SignedInfo><SignatureValue>b1fsjIbXZSi1kzMRobLksjJjQsNek3TT11vy+WZNDZpAIBoEIkzFR6MLk1OXxNBSkaQR+9mxC+ug
deu8/tS4Vz7fpg5DMXwFNxRH8is+HrNbuGcZnDuD/YFh547mm9pQy8xrpV+ubt7DBd0a+Da638UX
CPvLNXOIcGlXupldGlvKi1jxnZ6Gc3JBGUVQnfW2LzkaUQUVLPiRrYzethqUe+ZVuwxZ3CuaPg5F
sTyjzdx2Gps+hsgAqJokb4jJ4V89iKOmE/eAvDQTJVvCiUzv1jCO64RfuqQ1SsAmESfccmhePoqG
95678wJ0+EhL2R91DvDRdEQzp5sddOqHpn/o0g==</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>01DqzBsJTyMHT2S9MK5AIyFXNU646kwiOK3uymXIy9EW0nRKNKRkeIRTlGwX4wEnymGtGgX5B/Ij
1elkLN4VJ9GplDV+wf0Lp2i2q4E6uRiWIzsqq42MCQgv8Fq/IPqjqPbeP9yh/8YPmBiMehBmhQd3
qzl77C03k6d0yBIO5q/zXneTK9uFBNEL5yNpukrLGBcf3b9VHsjXpEaQrxGSMHCgNWpQgXpEcBr5
OJ0/XxWbgMCZMlkYe1d6gswjuCRZ/xxJwEfbSO5AsnPtyqxSIjyhgEi9REtYnzaWwOBN4JCqt0pM
L0ja23lUwVJuNwkwNGKBXvkGoXUln8Sf7PIv7w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature>


I have the base64 encoded public key with which I need to validate the signature. Can anybody please provide reference to some Objective C code that will help to achieve the signature validation?


Regards,

Chinmoy Das

Replies

You typically do this by combining a Common Crypto hash function (like

CC_SHA1
) with a Security framework verify function (
SecKeyRawVerify
). The CryptoCompatibility sample code has an example of this. Check out the QCCRSASHA1Verify class.

IMPORTANT This is a Mac sample but most of the APIs in question are also on iOS so the code just works on both platforms. One critical exception to this is the RSA primitives, which are different on both platforms. CryptoCompatibility deals with that by having separate implementations for OS X and iOS. For example, QCCRSASHA1Verify is the iOS class and QCCRSASHA1VerifyT is the OS X class (the “T” standards for “transform”, because it uses the OS X-specific security transforms API).

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

DTS will close for the winter holidays at the end of business on Wed, 23 Dec 2015 and re-open on Mon, 4 Jan 2016.

The input parameters are as below in QCCRSASHA1Verify

@property (atomic, copy, readonly ) NSData * inputData;
@property (atomic, assign, readonly ) SecKeyRef publicKey;
@property (atomic, copy, readonly ) NSData * signatureData;


I have an XML payload, with the data tags and a signature as below. Can you please guide how can I get the inputData and signatureData from this XML?



<?xml version="1.0" encoding="UTF-8"?>
<ns2:RespPay xmlns:ns2="http://npci.org/upi/schema/">
  <Head msgId="4" orgId="SBI" ts="2016-01-05T10:06:26+05:30" ver="1.0"/>
  <Txn id="1451968577855d0kSkoT80FjfpqOQ" note="Restaurant Bill " ts="2015-02-16T22:02:35+05:30" type="CREDIT">
    <RiskScores>
      <Score provider="sbi" type="TXNRISK" value="00030"/>
      <Score provider="NPCI" type="TXNRISK" value="00000"/>
    </RiskScores>
  </Txn>
  <Resp reqMsgId="5skv5ptRj1uMQhhxjtI" result="SUCCESS">
    <Ref addr="rohit.patekar@hdfc" approvalNum="ABCDE" respCode="00" seqNum="1" settAmount="4000" settCurrency="INR" type="PAYEE"/>
  </Resp>
  <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/2001/04/xmldsig-more#rsa-sha256"/>
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
        <DigestValue>085LNKbjlhiuoNOwohhRc1Yko9pWDAER5racn/b/SsQ=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>DtcBt8V2sIjidg8vObnDcHTKOZN1pcDv9YrnCMOu/jniQk2NP53d6eW12yM9oIksBMORSCkteRykLQCn9FoLYiEZIeXYuLOTkrIuiTJQBpEbnwbpRAGRs+ouR1fGluoHbcSwtSFsnHYOIccWRcTzf5xf99w1XAlR4jRlzKJDv48T08nq2jlG4jLumuPZB0UQ93ed8oMEMJTYfaN50hKtrpbWpXJCRHJ8Or1eeoVp4l1PV9QyCwG0bzWaoUs9KvxcFvkqOcrwJRzc8AKrMG0BqWAr8+JAywe+wq6bX0gnW92AJXizGXC2NiRQn/je0gOTPC4O5q+Pevc1urCSL4aAjQ==</SignatureValue>
    <KeyInfo>
      <KeyValue>
        <RSAKeyValue>
          <Modulus>01DqzBsJTyMHT2S9MK5AIyFXNU646kwiOK3uymXIy9EW0nRKNKRkeIRTlGwX4wEnymGtGgX5B/Ij1elkLN4VJ9GplDV+wf0Lp2i2q4E6uRiWIzsqq42MCQgv8Fq/IPqjqPbeP9yh/8YPmBiMehBmhQd3qzl77C03k6d0yBIO5q/zXneTK9uFBNEL5yNpukrLGBcf3b9VHsjXpEaQrxGSMHCgNWpQgXpEcBr5OJ0/XxWbgMCZMlkYe1d6gswjuCRZ/xxJwEfbSO5AsnPtyqxSIjyhgEi9REtYnzaWwOBN4JCqt0pML0ja23lUwVJuNwkwNGKBXvkGoXUln8Sf7PIv7w==</Modulus>
          <Exponent>AQAB</Exponent>
        </RSAKeyValue>
      </KeyValue>
    </KeyInfo>
  </Signature>
</ns2:RespPay>

It wouldn't help if I tell you how to produce inputData and signatureData. You need to verify that the DigestValue is correctly produced as well. That's really important for the validity of the signature, even if you can get inputData and signatureData and both checks out, the document signature isn't verified unless you checked that.


Thanks to the cryptography involved, it's better to use an XMLDSig verification library instead of by hand, but I have found none for iOS. There are plenty for Android though. If you intend to build one, the book Secure XML: The New Syntax for Signatures and Encryption by Kitty Niles; Donald E. Eastlake is the go-to introduction.