-
Notifications
You must be signed in to change notification settings - Fork 98
2.0 Signing Messages
- ✅ 2.0 | ⛔ 1.9 | ...
- Use an Intermediate Certificate (
digital-certificate.txt) and a private key (private-key.pem) to achieve silent printing.
| Component | Description |
|---|---|
private-key.pem |
🔑 Private key used for signing |
digital-certificate.txt |
🔒 Trusted, intermediate certificate |
Note: To override the Trusted Root certificate, launch QZ Tray using
java -DtrustedRootCert=MyRootCA.crt -jar qz-tray.jar.
- A language capable of reading an RSA private key and generating an SHA1 base64 encoded signature hash.
- Signing examples are available here:
assets/signing
-
Generate an Intermediate Certificate (
digital-certificate.txt). -
Edit
qz.security.setCertificatePromise()to use your Intermediate Certificate. -
Edit
qz.security.setSignaturePromise()to use your server-side signing method. -
Edit
sign-message.phpto sign print requests with your private key.
Examples in other languages can be find indemo/assets/signingof QZ Tray.
-
Note: Your
public-key.txtis not needed for signing. Store yourpublic-key.txtsecurely as you will need it for generating a new Intermediate Certificate when it expires.
A sample certificate chain is provided with the demo, labeled as "localhost". This will display a trusted message on load of the page.
- Edit the
setCertificatePromise()provided in thesample.htmlfile. - Replace the "localhost" certificate chain with your Intermediate Certificate by changing the
$.ajax(...)line to match the address of the certificate.
The Intermediate Certificate generated by QZ Industries, LLC is digital-certificate.txt
qz.security.setCertificatePromise(function(resolve, reject) {
$.ajax("assets/signing/digital-certificate.txt").then(resolve, reject);
});A new setSignaturePromise() 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
GETand if the print job is larger than a URI can fit, then it should bePOST-ed (generally has no size limit) -
Note:
GETwill also truncate all data after a#hash mark, sofindPrinter('foo#')won't work unless the code is switched fromGETtoPOST
Change the $.ajax(...) line to match the address of your php file.
qz.security.setSignaturePromise(function(toSign) {
return function(resolve, reject) {
$.ajax("assets/signing/sign-message.php?request=" + toSign).then(resolve, reject);
};
});qz.security.setSignaturePromise(function(toSign) {
return function(resolve, reject) {
$.post("assets/signing/sign-message.php", {request: toSign}).then(resolve, reject);
};
});.NET conveniently exposes a promise-friendly PageMethods object which is capable of calling a server-side .NET function by name directly from JavaScript. This assumes a server-side signing example has already been setup in C#, VB.NET, etc.
qz.security.setSignaturePromise(function (toSign) {
return function (resolve, reject) {
PageMethods.SignMessage(toSign, resolve, reject);
};
});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 qz.security.setSignaturePromise 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.
- 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
$PASSout of the line$privateKey = openssl_get_privatekey(file_get_contents($KEY), $PASS);if not password protected.
-
Make sure to edit this line:
$req = $_GET['request'];appropriately to edit the method you are using in the AJAX call (GETorPOST)
1. If these changes have been done correctly, you will be able to suppress this dialog box:

This will no longer come from an untrusted source.

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