Getting started with our timestamping API

Standard timestamping

When timestamping a file, a proof named timestamp seal is produced. This operation is applicable to any type of document, without limitation of size or extension. Only a fingerprint of the document is sent to the timestamping service.

Configuration

Universign offers two ways to access its timestamping service:

  • the timestamping protocol defined by the RFC 3161 standard. You just have to configure your client software.
  • a simple API based on a FORM sent in an HTTP POST request which can be implemented easily in any production platform.
Authentication parameters
Security SSL
Authentication method HTTP basic authentication
Credentials email and password
Access with the timestamping protocol (RFC3161)

URL: https://ws.universign.eu/tsa/

Access with a FORM sent by an HTTP POST request

URL: https://ws.universign.eu/tsa/post/
FORM parameters encoded with the mime-type 'application/x-www-form-urlencoded':

hashAlgo Name of the algorithm used to compute the hash: SHA256, SHA384 or SHA512
hashValue the hash of the document encoded in hexadecimal
withCert boolean (true or false) which indicates if the timestamping seals contains the certificate of the timestamping unit

The server will return the timestamp seal encoded in ASN.1 as a TimeStampToken as described in RFC3161.

Some code examples
In Python
          #!/usr/bin/python

          import urllib;
          import urllib2;
          import hashlib;
          import base64;

          # first we construct the parameters for the request
          data = {};
          data['hashAlgo'] = "SHA256";
          data['withCert'] = "true";
          data['hashValue'] = hashlib.sha256(dataToTimestamp).hexdigest();
          params = urllib.urlencode(data);

          # basic HTTP authentication is needed to access this service
          headers = {};
          auth = base64.encodestring(username + ":" + password);
          headers["Authorization"] = "Basic " + auth;

          # then the request itself
          request = urllib2.Request("https://ws.universign.eu/tsa/post/", params, headers);

          # all is ready, the request is made
          response = urllib2.urlopen(request);
          tsp = response.read();
          

In PHP
          $hashedDataToTimestamp = hash('sha256', $dataToTimestamp);
          $dataToSend = array ('hashAlgo' => 'SHA256', 'withCert' => 'true', 'hashValue' => $hashedDataToTimestamp);
          $dataQuery = http_build_query($dataToSend);
          $context_options = array (
                  'http' => array (
                      'method' => 'POST',
                      'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
                       ."Content-Length: " . strlen($dataQuery) . "\r\n"
                       ."Authorization: Basic ".base64_encode($login.':'.$password)."\r\n",
                      'content' => $dataQuery
                    )
                );

          $context = stream_context_create($context_options);
          $fp = fopen("https://ws.universign.eu/tsa/post/", 'r', false, $context);
          $tsp = stream_get_contents($fp);
          

In Java
          static InputStream doTsp(String login, String pwd, String hash, String algo) 
            throws Exception
          {
            URLConnection conn = new URL("https://ws.universign.eu/tsa/post/").openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            String authString = login + ":" + pwd;
            String authStringEnc = Base64.encode(authString);
            conn.setRequestProperty("Authorization", "Basic " + authStringEnc);

            OutputStream out = conn.getOutputStream();
            String params = "hashAlgo=" + URLEncoder.encode(algo, "UTF-8") + "&hashValue="
                + URLEncoder.encode(hash, "UTF-8") + "&withCert=" + URLEncoder.encode("false", "UTF-8");
            out.write(params.getBytes("UTF-8"));
            out.flush();

            return conn.getInputStream();
          }
          

Any doubt or question? Don't hesitate to contact us.


PDF timestamping

PDF timestamp differs from common file timestamp as the timestamp seal is embedded in the PDF. During the timestamp operation, the source document must be sent entirely to affix the seal.

Configuration

Universign offers two ways to access its timestamping service:

  • the communication protocol XML-RPC which allows the transmission of parameter from any platform.
  • a simple API based on a FORM sent in an HTTP POST request which can be implemented easily in any production platform.
Some code examples
In Python
                import xmlrpclib;

                if __name__ == "__main__":
                pdfDocument = xmlrpclib.Binary(open("myDoc.pdf").read())

                proxy = xmlrpclib.ServerProxy("https://me@myCompany.com:myPwd@ws.universign.eu/tsa/pdf/rpc")
                myTimestampedPdfDocument = proxy.timestamper.timestamp(pdfDocument)
                f = open("myTimestampedDoc.pdf", "w+")
                f.write(myTimestampedPdfDocument.data)
                f.close()
              

In PHP
                $destination = "https://".$login.':'.$password."@ws.universign.eu/tsa/pdf/post/";
								
                $eol = "\r\n";
                $data = '';
                $mime_boundary = md5(time());
                $data .= '--'.$mime_boundary.$eol;
                $data .= 'Content-Disposition: form-data; name="file"; filename="'.$fileName.'"'.$eol;
                $data .= 'Content-Type: text/plain'.$eol;
                $data .= 'Content-Transfert-Encoding: base64'.$eol.$eol;
                $data .= $dataToTimestamp.$eol;
                $data .= "--".$mime_boundary."--".$eol.$eol;
                $params = array('http' => array(
                        'method' => 'POST',
                        'header' => 'Content-Type: multipart/form-data; boundary='.$mime_boundary.$eol,
                        'content' => $data
                ));


                $context = stream_context_create($params);

                $tsp = @file_get_contents($destination, FILE_TEXT, $context);
							

Any doubt or question? Don't hesitate to contact us.


Troubleshootings

Universign timestamping service is available 24/7 and limited to one seal per second.

Your Universign account will not be debited if an error occurs during the timestamping process.

When a request fails, Universign returns an error code that will enable you to understand and to solve the problem.

400 - incorrect request or not supported.
401 - authentication problem: user unknown or incorrect password.
403 - account problem: no more seals available or package expired.
404 - resource not found, it might be an URL error.
500 - Universign service internal error. Please try again later or contact our support.