PhenixID DocumentationPhenixID Signing ServicesPhenixID Signing ServiceDeveloper integration guideUsing Trusted Central Signing Service - API - Transaction (XML) signing

Using Trusted Central Signing Service - API - Transaction (XML) signing

Overview

The api contains two functions, sign and verify.

Sign:

1. Send XML file to be signed to the api. Api will return a id value

2. Create signed jwt token with payload attributes id=<value performed from previous step>, successURL=<URL where PhenixID Signing Service should redirect the browser after successful signing>, failURL=<URL where PhenixID Signing Service should redirect the browser after unsuccessful signing>

3. Redirect user browser to URL?Authorization=<jwt_token>

4. User perform sign against PhenixID Signing Services

5. After successful sign and redirect back, perform new call to API to fetch signed XML file.

6. Store the signed XML file.

 

Verify:

1. Send signed XML file to API

 

2. API will return signature status and data about the signatory(ies)

Prerequisites

- PhenixID Signing Service - Trusted Central Signing Service - API - Transaction (XML) signing configured.

- Username and password for API authentication

- Base URL for PhenixID Signing Services

- Keypair and certificate (.p12 file) for signing jwt tokens. This cert can be selfsigned.

Fetch data to be signed

Fetch the data (text) to be signed. Put the data into a xml structure:

<?xml version="1.0" encoding="utf-8"?>
<message>
    REPLACE_THIS_WITH_YOUR_TEXT
</message>

 

Example:

<?xml version="1.0" encoding="utf-8"?>
<message>
    I hereby sign that the patient is Donald Duck.
</message>

Send unsigned xml - api call

Request

Method: HTTP POST

Endpoint: /files/integration_dev (may vary depending on backend configuration)

Headers:

Name Value
Mandatory Comment
Content-Type application/xml Yes
Authorization <basic_auth_value> No If applicable, username and password must be given to you by PhenixID Signing Service admin.

Body:

The xml content is put in the body.

Example request

 

POST /files/integration_dev HTTP/1.1
Host: demo.phenixid.net
Content-Type: application/xml
Authorization: Basic c2lnbl9hcGk6c2VjcmV0


<?xml version="1.0" encoding="utf-8"?>
<message>
    I hereby sign that the patient is Donald Duck.
</message>

Response

Example response

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 167
{
    "id": "a38cbd6e-e017-4e5c-9476-2c2635ae1ef2",
    "content_type": "application/xml; charset=UTF-8",
    "size": 168,
    "created": "2018-10-29T20:05:51.366Z"
}

Create JWT token

Create keypair and certificate to be able to sign jwt token

Create a keypair and certificate for signing jwt token. The certificate (public crt) must be distributed to PhenixID Server administrator.

Populate jwt payload

Populate the jwt with these properties:

Key Value
jti Unique ID of token. Generate random unique key.
iat Issued at value. Now in epoch time.
nbf Not before value. Now in epoch time.
exp Expires value. Now + 10 minutes in epoch time.
id Id value. The id returned from the first api call.
successURL The url where PhenixID Signing Service should redirect the browser after successful sign.
failURL The url where PhenixID Signing Service should redirect the browser after unsuccessful sign.
cancelURL
The url where PhenixID Signing Service should redirect the browser if user cancels during the signing process.

Example:

{
  "jti": "123123123123456456",
  "iat": 1521815800,
  "exp": 1521815830,
  "nbf": 1521815800,
  "id": "a38cbd6e-e017-4e5c-9476-2c2635ae1ef2",
  "failURL": "https://example.org/callback/sign_failure",
  "successURL": "https://example.org/callback/sign_success",
"cancelURL" : "https://example.org/callback/sign_cancel"
}

Sign jwt token

Sign the payload with the certificate created in previous step using this algorithm.

{

 "alg": "RS256",

 "typ": "JWT"

}

 

JWT token value

JWT token value should now look something like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk0YTg1MjMxLWZhYWMtNGQxZC1iZTk1LWY5ZGY2ZjA3ODI5YSIsImp0aSI6IjEyMzEyMzEyMzEyMzQ1NjQ1NiIsImlzcyI6IkV4YW1wbGUgb3JnIiwiaWF0IjoxNTIxODE1ODAwLCJleHAiOjE1MjE4MTU4MzAsImF1ZCI6ImludGVncmF0aW9uLnBoZW5peGlkLnNlIiwic3ViIjoibXl1c2VyIiwiZmFpbFVSTCI6Imh0dHBzOi8vZXhhbXBsZS5vcmcvc2lnbl9mYWlsdXJlIiwic3VjY2Vzc1VSTCI6Imh0dHBzOi8vZXhhbXBsZS5vcmcvc2lnbl9zdWNjZXNzP2lkPTY5N2QxNmM5LTI4MzYtNGY5Ni1iYTM4LTJiY2I1NzdmOTg0MiJ9.H9bqf0cEpOWvm8zWNcEflIwb6zCHx_bcxXfuQP71zOk

Fetch signature result - the signed XML

When PhenixID Signing Services redirected the user agent back to the success URL, perform this callout to the API to fetch the signed XML.

 

Fetch signed file - api call

Method: HTTP GET

Endpoint: /files/integration_dev/<id_fetched_in_first_api_call> (may vary depending on backend configuration

Headers:

Name Value Mandatory Comment
Content-Type application/xml Yes
Authorization <basic_auth_value> No If applicable, username and password must be given to you by PhenixID Signing Service admin.

Example request

GET /files/integration_dev/a38cbd6e-e017-4e5c-9476-2c2635ae1ef2 HTTP/1.1
Host: demo.phenixid.net
Content-Type: application/xml
Authorization: Basic c2lnbl9hcGk6c2VjcmV0
Cache-Control: no-cache

Response

Response

The response contains the signed XML data.

Example:

<?xml version="1.0" encoding="UTF-8"?>
<message>
    I hereby sign that the patient is Donald Duck
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-36cf85c54c8b1d5431bd198926858840">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            <ds:Reference Id="r-id-1" Type="" URI="">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
                        <ds:XPath>not(ancestor-or-self::ds:Signature)</ds:XPath>
                    </ds:Transform>
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <ds:DigestValue>JErU76UbbEptbyLC7IflJ8dnCfbaFJ9F0bon0umnju0=</ds:DigestValue>
            </ds:Reference>
            <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xades-id-36cf85c54c8b1d5431bd198926858840">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <ds:DigestValue>pQO1EO4aDpN876bx2lA8B11m10cgxTd2k0kqmzBniGg=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue Id="value-id-36cf85c54c8b1d5431bd198926858840">mTQjptkrjU696LBb87kVnXI1FoprWyIPODvAQI4KKS8uAu7YwP6l9MUXpSBBGjJtl3xmQwi1lVGjLOGvKjwHUx1Mg2i/hUB8S6Fig58zM3sBRnbquoupSuJn2yEtpk/1+HByAhQ8rooiykpUACyAgHqu4MH+Zl5TMeA37OoNs3Fh9H04BW/YvFZE7s28dhbrMZ5fELsTBy4Zip+3rQEuGHEcQH2YUPLY7ny8er1gE/io/lbfla0puGSNR7wnNsL8AY/2jPBxealquKP9gQkMpLx4a/6z2UiHHRGgrB+HQ9e2Nc5DSEc5481AW5x2mBdwh8GDG1UuuOOjWp9jTqrucw==</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>MIIDYDCCAkigAwIBAgIBFjANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEVMBMGA1UEBxMMTmFja2EgU3RyYW5kMQ8wDQYDVQQKEwZNY0FmZWUxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRowGAYDVQQDExFFQSBERU1PIHVzZXIgQ0EgMTAeFw0xNDA1MjMxMjA3MDBaFw0xOTA1MjMxMjA3MDBaMEIxDjAMBgNVBAMTBWJodWxsMQ0wCwYDVQQEEwRIdWxsMQ4wDAYDVQQqEwVCb2JieTERMA8GA1UEBRMIMTk2NTE5NjYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8yVowqmpfeKptuigqFHjeKC/CViAMexnbgCYdbo9atIc08b35lV364uTpkafupgAexTi9X1GOuKEM4KKgAQQ91sSPJeuz7r6Y5EN5HO/dEXtuQXb1TwZ2FGvDEEaeFigQyNALxnUrhWyfwSceU3ev4j+QbGpRuX7MfYT6BZbmrWyV0+j/mIHq9dfLcp48wfTPh6VXo1iHCYQVtn3ZFHP7oFtb/xyJi62dvFqrsnEbFkfmRN+sRmgfJtC90jjPvbjMsUHaKmYh99FrK26e1N2T8cxZsH/3Xx2hpE1jL9TolrV+YQ5XdFfJRHeAoG0zX7rtt722kMOAJq+eNBpRXXejAgMBAAGjPDA6MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPOypDuauffXkwjNdeNti0IkYSpdMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAMAxB95G/XCOetwAM1KXt7qH+tU0mvbXHqgWdyHRFHeayQjmKp3831ciNWEYDSBvGoUz2FI0WQjrBETDXkwoXRxFf81o8SSFkC2HpitqUW/on+lH4v2u7U2yaO5rUXwFsiU63NrJIPttjDzyJcHFVXq1JrnRWDYq8X0JaTh3RU9Pww8eN2dw8MjHLDtgxZg3vPElkSWaDTse/HfQPBc0cAc2D7/HOj3qyrEqIDrHHmQBTkC5S9C/O1sEhpJktqi8SMUmmniVhhR5v5MVNPGlIDzQwJ9nXWzdBz5wmQqLkw2/853OujVK2ZXcKB6e9GklHBw5YtFItbMmVvuxCn5TfcQ==</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
        <ds:Object>
            <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#id-36cf85c54c8b1d5431bd198926858840">
                <xades:SignedProperties Id="xades-id-36cf85c54c8b1d5431bd198926858840">
                    <xades:SignedSignatureProperties>
                        <xades:SigningTime>2018-05-24T14:19:23Z</xades:SigningTime>
                        <xades:SigningCertificateV2>
                            <xades:Cert>
                                <xades:CertDigest>
                                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                                    <ds:DigestValue>zv6AIBG/TgGKdEkWwiCn4d2MPE0=</ds:DigestValue>
                                </xades:CertDigest>
                                <xades:IssuerSerialV2>MHAwa6RpMGcxCzAJBgNVBAYTAlNFMRUwEwYDVQQHEwxOYWNrYSBTdHJhbmQxDzANBgNVBAoTBk1jQWZlZTEUMBIGA1UECxMLRW5naW5lZXJpbmcxGjAYBgNVBAMTEUVBIERFTU8gdXNlciBDQSAxAgEW</xades:IssuerSerialV2>
                            </xades:Cert>
                        </xades:SigningCertificateV2>
                    </xades:SignedSignatureProperties>
                    <xades:SignedDataObjectProperties>
                        <xades:DataObjectFormat ObjectReference="#r-id-1">
                            <xades:MimeType>application/octet-stream</xades:MimeType>
                        </xades:DataObjectFormat>
                    </xades:SignedDataObjectProperties>
                </xades:SignedProperties>
            </xades:QualifyingProperties>
        </ds:Object>
    </ds:Signature>
</message>

 

Verify signature - api call

Method: HTTP PUT

Endpoint: /pipes/verifysign_xml (may vary depending on backend configuration

Headers:

Name Value Mandatory Comment
Content-Type application/xml Yes
Authorization <basic_auth_value> No If applicable, username and password must be given to you by PhenixID Signing Service admin.

Body:

The xml file content is sent in the body.

 

Example request:

PUT /pipes/verifysign_xml HTTP/1.1

Host: demo.phenixid.net

Content-Type: application/xml

 <?xml version="1.0" encoding="UTF-8"?>

<message>

   I hereby sign that the patient is Donald Duck

   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-36cf85c54c8b1d5431bd198926858840">

       <ds:SignedInfo>

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

           <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>

           <ds:Reference Id="r-id-1" Type="" URI="">

               <ds:Transforms>

                   <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">

                       <ds:XPath>not(ancestor-or-self::ds:Signature)</ds:XPath>

                   </ds:Transform>

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

               </ds:Transforms>

               <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>

               <ds:DigestValue>JErU76UbbEptbyLC7IflJ8dnCfbaFJ9F0bon0umnju0=</ds:DigestValue>

           </ds:Reference>

           <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xades-id-36cf85c54c8b1d5431bd198926858840">

               <ds:Transforms>

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

               </ds:Transforms>

               <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>

               <ds:DigestValue>pQO1EO4aDpN876bx2lA8B11m10cgxTd2k0kqmzBniGg=</ds:DigestValue>

           </ds:Reference>

       </ds:SignedInfo>

       <ds:SignatureValue Id="value-id-36cf85c54c8b1d5431bd198926858840">mTQjptkrjU696LBb87kVnXI1FoprWyIPODvAQI4KKS8uAu7YwP6l9MUXpSBBGjJtl3xmQwi1lVGjLOGvKjwHUx1Mg2i/hUB8S6Fig58zM3sBRnbquoupSuJn2yEtpk/1+HByAhQ8rooiykpUACyAgHqu4MH+Zl5TMeA37OoNs3Fh9H04BW/YvFZE7s28dhbrMZ5fELsTBy4Zip+3rQEuGHEcQH2YUPLY7ny8er1gE/io/lbfla0puGSNR7wnNsL8AY/2jPBxealquKP9gQkMpLx4a/6z2UiHHRGgrB+HQ9e2Nc5DSEc5481AW5x2mBdwh8GDG1UuuOOjWp9jTqrucw==</ds:SignatureValue>

       <ds:KeyInfo>

           <ds:X509Data>

               <ds:X509Certificate>MIIDYDCCAkigAwIBAgIBFjANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEVMBMGA1UEBxMMTmFja2EgU3RyYW5kMQ8wDQYDVQQKEwZNY0FmZWUxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRowGAYDVQQDExFFQSBERU1PIHVzZXIgQ0EgMTAeFw0xNDA1MjMxMjA3MDBaFw0xOTA1MjMxMjA3MDBaMEIxDjAMBgNVBAMTBWJodWxsMQ0wCwYDVQQEEwRIdWxsMQ4wDAYDVQQqEwVCb2JieTERMA8GA1UEBRMIMTk2NTE5NjYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8yVowqmpfeKptuigqFHjeKC/CViAMexnbgCYdbo9atIc08b35lV364uTpkafupgAexTi9X1GOuKEM4KKgAQQ91sSPJeuz7r6Y5EN5HO/dEXtuQXb1TwZ2FGvDEEaeFigQyNALxnUrhWyfwSceU3ev4j+QbGpRuX7MfYT6BZbmrWyV0+j/mIHq9dfLcp48wfTPh6VXo1iHCYQVtn3ZFHP7oFtb/xyJi62dvFqrsnEbFkfmRN+sRmgfJtC90jjPvbjMsUHaKmYh99FrK26e1N2T8cxZsH/3Xx2hpE1jL9TolrV+YQ5XdFfJRHeAoG0zX7rtt722kMOAJq+eNBpRXXejAgMBAAGjPDA6MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPOypDuauffXkwjNdeNti0IkYSpdMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAMAxB95G/XCOetwAM1KXt7qH+tU0mvbXHqgWdyHRFHeayQjmKp3831ciNWEYDSBvGoUz2FI0WQjrBETDXkwoXRxFf81o8SSFkC2HpitqUW/on+lH4v2u7U2yaO5rUXwFsiU63NrJIPttjDzyJcHFVXq1JrnRWDYq8X0JaTh3RU9Pww8eN2dw8MjHLDtgxZg3vPElkSWaDTse/HfQPBc0cAc2D7/HOj3qyrEqIDrHHmQBTkC5S9C/O1sEhpJktqi8SMUmmniVhhR5v5MVNPGlIDzQwJ9nXWzdBz5wmQqLkw2/853OujVK2ZXcKB6e9GklHBw5YtFItbMmVvuxCn5TfcQ==</ds:X509Certificate>

           </ds:X509Data>

       </ds:KeyInfo>

       <ds:Object>

           <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#id-36cf85c54c8b1d5431bd198926858840">

               <xades:SignedProperties Id="xades-id-36cf85c54c8b1d5431bd198926858840">

                   <xades:SignedSignatureProperties>

                       <xades:SigningTime>2018-05-24T14:19:23Z</xades:SigningTime>

                       <xades:SigningCertificateV2>

                           <xades:Cert>

                               <xades:CertDigest>

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

                                   <ds:DigestValue>zv6AIBG/TgGKdEkWwiCn4d2MPE0=</ds:DigestValue>

                               </xades:CertDigest>

                               <xades:IssuerSerialV2>MHAwa6RpMGcxCzAJBgNVBAYTAlNFMRUwEwYDVQQHEwxOYWNrYSBTdHJhbmQxDzANBgNVBAoTBk1jQWZlZTEUMBIGA1UECxMLRW5naW5lZXJpbmcxGjAYBgNVBAMTEUVBIERFTU8gdXNlciBDQSAxAgEW</xades:IssuerSerialV2>

                           </xades:Cert>

                       </xades:SigningCertificateV2>

                   </xades:SignedSignatureProperties>

                   <xades:SignedDataObjectProperties>

                       <xades:DataObjectFormat ObjectReference="#r-id-1">

                           <xades:MimeType>application/octet-stream</xades:MimeType>

                       </xades:DataObjectFormat>

                   </xades:SignedDataObjectProperties>

               </xades:SignedProperties>

           </xades:QualifyingProperties>

       </ds:Object>

   </ds:Signature>

</message>

Example response:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 154
{
    "success": true,
    "error_message": "",
    "error_detail_message": "",
    "items": [
        {
            "id": "verifyxml",
            "properties": {
                "intact": [
                    "false"
                ],
                "when": [
                    "2018-05-24T14:19:23Z"
                ],
                "who": [
                    "bhull"
                ]
            }
        }
    ]
}