Proof of Private Key Possesion on Digitally Signed Documents
A small step to verify a digitally signed document that has been printed. Create a dynamic SVG with a hash of your private key and time.
When someone prints a digitally signed document, there is no way to verify it other than visually compare the digital and physical copies. By adding a dynamic image with the hash of your private key and the approximate time, you can get a small level of verification. While this only proves possession of a private key, it can help you if someone decides to use a printed copy of the document. If know of a better idea, please let me know. I would appreciate it!
In my post on how to Create and Use Certificates for Digitally Signing PDFs in Linux, a PKCS #12 file was created and added to a Network Security Services (NSS) database. This post assumes you have the standard setup described in that article.
Extract the certificate
You may not have a certificate file if you use an NSS database. If you do have a certificate (i.e. a .p12 file) then skip to the next subheading.
List the certificates in your NSS database so you can find the one you want to extract.
1
certutil -d ~/.pki/nssdb/ -L
Extract the certificate from your NSS database. Replace Nickname of my certificate
with the actual nickname you saw from the previous command.
1
pk12util -d nssdb/ -n 'Nickname of my certificate' -o my-signing-certificate.p12
Generating a dynamic image
A base SVG image will be needed. A BASH script will be used fill placeholder text and create a modified version of the SVG.
Create the base SVG
Create an SVG to use as your base image. Use Inkscape or whatever app you prefer. The SVG should be 800x300 pixels. This way it will be wide enough for a hash and some other text. The SVG should have the following placeholder text.
- %timestamp%
- This will be replaced with a Unix timestamp.
- %checksum%
- This will be replaced with the checksum of your public key and a timestamp of the current time.
Here is an example SVG that was created using the description above.
Generating the dynamic image
Copy and paste the script below. Save it at ~/.pki/signature-background-generator.sh
. Be sure to adjust any of the variables at the top of the script to suite your needs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash
# This script replaces placeholder text in an SVG file with a timestamp and a MD5 checksum.
# The placeholder values to search/replace in the SVG.
placeholder_checksum='%checksum%';
placeholder_timestamp='%timestamp%';
# The base SVG file
base_svg='/home/username/.pki/signature-background-base.svg';
# The certificate file.
certificate_file='/home/username/.pki/my-signing-certificate.p12';
# The output file path.
output_file='/home/username/.pki/signature-background.svg';
# Check if the base file actually exists.
if [ ! -f "$base_svg" ]; then
echo "Error: File not found at '$base_svg'";
exit 1;
fi
# Check if the placeholders exists in the file before proceeding.
if ! grep -qF "$placeholder_checksum" "$base_svg"; then
echo "Error: Placeholder '$placeholder_checksum' not found in '$base_svg'.";
exit 1;
fi
if ! grep -qF "$placeholder_timestamp" "$base_svg"; then
echo "Error: Placeholder '$placeholder_timestamp' not found in '$base_svg'.";
exit 1;
fi
# Get the current Unix timestamp.
timestamp=$(date '+%s');
# Calculate the MD5 checksum of the certificate text and unix timestamp.
# awk is used to only store the checksum.
checksum=$((cat $certificate_file && date +%s%N) | md5sum | awk '{print $1}')
# Search and replace placeholder text.
sed "s|$placeholder_checksum|$checksum|g" "$base_svg" > $output_file;
sed -i "s|$placeholder_timestamp|$timestamp|g" $output_file;
Now that the script is ready, make it executable.
1
chmod +x ~/.pki/signature-background-generator.sh
Automatically generate the dynamic image
You have to remember to run the script any time you are going to be signing. If you are happy with that, you are done. If you want the image automatically generated, then set up a cron. Assuming you placed the script in ~/username/.pki/
, add a cron entry. Run crontab -e
and paste this at the bottom.
1
2
# Runs the SVG background image generator every 2 minutes.
*/2 * * * * /home/username/.pki/signature-background-generator.sh > /dev/null 2>&1
Now you have a background image that will be generated every 2 minutes. When signing documents in Okular, there is an option to add a background image. Select the image at ~/.pki/signature-background.svg
and you are set.