Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

1.9 Signing Messages

klabarge edited this page Sep 7, 2016 · 5 revisions

Compatibility

  • ⛔ 2.x | ✅ 1.9 | ...

Objective

This guide will show you how to properly use your Intermediate (Trusted) Certificate and your private key to achieve silent printing. If you are unsure how to do this, learn how to generate an Intermediate Signing Certificate here.

Optional: To override the Trusted Root certificate, launch QZ Tray using java -DtrustedRootCert=MyRootCA.crt -jar qz-tray.jar.

  • A certificate request may be done at a later time if you wish to set the technical signing first.
  • Signing samples can be found in demo/assets/signing. A sample private key is also provided.
  • The samples provided with the software will NOT suppress the print warnings.

Steps

  1. Generate an Intermediate Certificate (digital-certificate.txt).
  2. Edit function getCertificate() to use your Intermediate Certificate.
  3. Edit function signRequest() to use your server-side signing method.
  4. Edit sign-message.php to sign print requests with your private key.
    Examples in other languages can be find in demo/assets/signing of QZ Tray.
  • Note: Your public key is not needed for signing. Store your public key securely as you will need it for generating a new Intermediate Certificate when it expires.

Supplying QZ with the Intermediate (Trusted) Certificate

A new getCertificate(...) function has been added to QZ Tray to allow the quick whitelisting of REQUEST communication from a trusted host to the QZ Tray application.

A sample certificate chain is provided with the demo, labeled as "localhost". This will display a trusted message on load of the page. This certificate will NOT REMOVE WARNINGS FOR SEND communication. SEND communication is only allowed when messages are signed using the same private key used to generate the CSR.

  1. Edit the getCertificate function provided in the sample.html file.

  2. Replace the "localhost" certificate chain with the Intermediate Certificate provided by QZ Industries, LLC by changing the url: line to match the address of the certificate. The Intermediate Certificate generated by QZ Industries, LLC is digital-certificate.txt

       function getCertificate(callback) {
       $.ajax({
            method: 'GET',
            url: 'assets/auth/digital-certificate.txt', //edit this line to match the address of your certificate
            async: false,
            success: callback // Data returned from ajax call should be the site certificate
        });

Signing the Privileged SEND Communication

A new signRequest(...) function has been added to the software to prevent anonymous printing. This is a security measure to ensure the identity of websites can be verified by the software.

  • Note: Print jobs are sent to the server as GET and if the print job is larger than a URI can fit, then it should be POST-ed (generally has no size limit)
  • Note: GET will also truncate all data after a # hash mark, so findPrinter('foo#') won't work unless the code is switched from GET to POST
  1. Change the url line to match the address of your php file.
  2. Comment out the line callback();

GET Method

function signRequest(toSign, callback) {
   $.ajax({
      method: 'GET',
      url: '/secure/url/for/sign-message.php?request=' + toSign, //edit this line
      async: false,
      success: callback // Data returned from ajax call should be the signature
   }); 

 //Send unsigned messages to socket - users will then have to Allow/Deny each print request
 callback(); //comment out this line
}

POST Method

function signRequest(toSign, callback) {
   $.ajax({
      method: 'POST',
      url: 'assets/signing/sign-message.php',
      data: { request: toSign },
      async: false,
      success: callback // Data returned from ajax call should be the signature
    });
}

Server-side Signing Method

A server-side signing method must be used in combination with the AJAX call. This signing will happen with your company's private key.

  • This private key MUST be 2048-bit
  • If generated by QZ Industries, LLC the file name will be private-key.pem

Trusted websites with a valid public key chain pair and a properly configured signRequest(...) AJAX function will automatically print to QZ Tray. Untrusted websites will continue to show a warning dialog.

In this example we go over how to accomplish this in php by editing the sign-message.php file that is provided with the software (demo/assets/signing/sign-message.php). Examples in other languages including: Ruby, Python, JavaScript, C#, J#, Java, ASP and VB can be found here.

  1. Change the line $KEY = 'private-key.pem'; to match the name of your private key
  • $PASS = ' ' is not needed if the private key file is not password protected.

  • Make sure to delete $PASS out of the line $privateKey = openssl_get_privatekey(file_get_contents($KEY), $PASS); if not password protected.

    <?php
    // #########################################################
    // #                     PHP Signing                       #
    // #########################################################
    // Sample key.  Replace with one used for CSR generation
    $KEY = 'private-key.pem';
    $PASS = 'S3cur3P@ssw0rd'; //Comment out/delete if the private key is not password protected

$req = $_GET['request']; $privateKey = openssl_get_privatekey(file_get_contents($KEY), $PASS); //use syntax below if file is not password protected //$privateKey = openssl_get_privatekey(file_get_contents($KEY));

$signature = null; openssl_sign($req, $signature, $privateKey);

if ($signature) { header("Content-type: text/plain"); echo base64_encode($signature); exit(0); }

echo '

Error signing message

'; exit(1); ?>
1. If these changes have been done correctly, you will be able to suppress this dialog box:

![image](https://cloud.githubusercontent.com/assets/12505463/8151249/1a16ce4a-12d6-11e5-821e-052513345e71.png)

This will no longer come from an untrusted source. 

![image](https://cloud.githubusercontent.com/assets/12505463/8245927/d6e8da60-1603-11e5-9f7b-27f6650b5d5f.png)

The new certificate should look similar to this (trusted, valid, and has a fingerprint):

![image](https://cloud.githubusercontent.com/assets/12505463/8245953/312f15c0-1604-11e5-8f24-d65a5b4d2119.png)