DEV Community

Franklin Yu
Franklin Yu

Posted on

signify: replacement for PGP signing?

OpenBSD is a security-focused, free and open-source, Unix-like operating system based on the Berkeley Software Distribution (BSD). Theo de Raadt created OpenBSD in 1995 by forking NetBSD 1.0. The OpenBSD project emphasizes portability, standardization, correctness, proactive security, and integrated cryptography.

OpenBSD is a Unix-like operating system focusing on security. Like all other unix-like open-sourced operating system, OpenBSD has its package manager, and packages are signed. However, all other Unix-like open-sourced operating systems sign their packages with GnuPG:

GNU Privacy Guard is a free-software replacement for Symantec's PGP cryptographic software suite. The software is compliant with RFC 4880, the IETF standards-track specification of OpenPGP. Modern versions of PGP are interoperable with GnuPG and other OpenPGP-compliant systems. GnuPG is however expected, as of April 2024, to break compliance with the upcoming revision of OpenPGP and thus with other implementations that will continue to comply.

In contrast, OpenBSD wrote their own tool for it: signify. As mentioned in the blog, it focuses on one thing, and does it well: sign a piece of data. It is much simpler than GnuPG (or OpenPGP in general), therefore a smaller attack surface, and therefore more secure.

Unfortunately, the tool is only for OpenBSD, not portable. There is a port to macOS (packaged in Homebrew and MacPorts):

GitHub logo jpouellet / signify-osx

OS X port of OpenBSD's signify(1)

macOS port of OpenBSD's signify(1)

This macOS port of OpenBSD's signify utility intentionally tracks upstream OpenBSD sources directly, keeping only the smallest portability layer possible with the explicit #1 goal of making it as easy to audit as possible.

The latest version was tested on macOS 10.14.2 with Apple LLVM 9.1.0.

Older versions were previously tested as far back as OS X 10.6.8 with GCC 4.2.1.

Some of the OpenBSD-specific functions used by signify that previously required portability shims were introduced in macOS 10.12(.1), and the corresponding portability shims have been removed to keep the code as lean and easily auditable as possible. If you need support for a newer signify on an older macOS, feel free to open an issue.

Man page at https://man.openbsd.org/signify.1

src/ is the result of make fetch (cvs get) and make hash-helpers (sed) as of the time of the last commit.

If you don't trust…

There is another portable version, more popular and apparently better maintained:

GitHub logo aperezdc / signify

OpenBSD tool to sign and verify signatures on files. Portable version.

Signify - Sign and Verify

Build Status

OpenBSD tool to sign and verify signatures on files. This is a portable version which uses libbsd (version 0.11 or newer is required).

See https://www.tedunangst.com/flak/post/signify for more information.

License

Signify is distributed under the terms of the ISC license.

Installation

Some GNU/Linux distributions have readily available packages in their repositories. It is recommended to use these, unless you absolutely need to build from source code:

  • Alpine Linux: apk add signify
  • Arch Linux: pacman -S signify
  • Debian/Ubuntu: apt install signify-openbsd
  • CentOS/RHEL/Rocky: dnf install epel-release then dnf install signify
  • Fedora: dnf install signify

Building

Dependencies

  • GNU Make (any version above 3.70).
  • C compiler. Both GCC and Clang are tested and supported.
  • libbsd 0.11 or newer.

If your system does not provide a package for libbsd, it is possible to use a bundled copy, check the build options section for more details.

Options

The following options…

However, two concerns are still mentioned in this Whonix forum post:

signify-openbsd - Development - Whonix Forum

https://www.openbsd.org/papers/bsdcan-signify.html https://kushaldas.in/posts/using-signify-tool-for-sign-and-verification.html https://manpages.debian.org/signify-openbsd

favicon forums.whonix.org

First, the signature format doesn’t support embedding filename or timestamp; second, signify only signs files that fit in RAM (1 GiB by default). The second concern is also mentioned in GitHub:

large file support #42

Created a 2G file for test purposes.

fallocate -l 2G test.img

Tried to sign it.

signify-openbsd -S -s ./keyname.sec -m ./test.img -x ./test.img.sig

result:

signify-openbsd: msg too large in ./test.img

Could you please add support for signing arbitrarily large files?

The Whonix forum post mentioned that a partially-compatible project minisign can help:

GitHub logo jedisct1 / minisign

A dead simple tool to sign files and verify digital signatures.

CodeQL scan

Minisign

Minisign is a dead simple tool to sign files and verify signatures.

For more information, please refer to the Minisign documentation

Tarballs and pre-compiled binaries can be verified with the following public key:

RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3

Compilation / installation

Using Zig:

Dependencies:

Compilation:

$ zig build -Drelease

Using cmake and gcc or clang:

Compilation:

$ mkdir build
$ cd build
$ cmake ..
$ make
# make install

Alternative configuration for static binaries:

$ cmake -D STATIC_LIBSODIUM=1 ..

or:

$ cmake -D BUILD_STATIC_EXECUTABLES=1 ..

Minisign is also available in Homebrew:

$ brew install minisign

Minisign is also available in Scoop on Windows:

$ scoop install minisign

Minisign is also available in chocolatey on Windows:

$ choco install minisign

Minisign is also available with docker:

$ docker run -i --rm jedisct1/minisign

The image can be verified with the following cosign public key:

-----BEGIN PUBLIC

Its “trusted comments” feature addresses the first concern; for example, projects can define machine-readable format for the trusted comment. It addresses the second concern by pre-hashing the file with BLAKE:

BLAKE is a cryptographic hash function based on Daniel J. Bernstein's ChaCha stream cipher, but a permuted copy of the input block, XORed with round constants, is added before each ChaCha round. Like SHA-2, there are two variants differing in the word size. ChaCha operates on a 4×4 array of words. BLAKE repeatedly combines an 8-word hash value with 16 message words, truncating the ChaCha result to obtain the next hash value. BLAKE-256 and BLAKE-224 use 32-bit words and produce digest sizes of 256 bits and 224 bits, respectively, while BLAKE-512 and BLAKE-384 use 64-bit words and produce digest sizes of 512 bits and 384 bits, respectively.

This project also seems to be more active than the previous two ports, so it makes sense to sign binary releases (especially big files like disk images) with minisign instead of signify. signify remains feasible for small files like emails or plain text files.

Note that minisign is only one-way compatible with signify in that minisign legacy signatures (i.e. signed with the -l switch) can be verified by signify. See:

Can't verify Signify signatures #59

Macil avatar
Macil posted on

Minisign gives me an error when I try to use it to verify a signature made by Signify. From the docs it seems like this is intended to work.

$ echo VGhpcyBpcyBhIHRlc3QgbWVzc2FnZS4K | base64 --decode > message.txt
$ signify -G -p sign.pub -s sign.sec
passphrase: (z)
confirm passphrase: (z)
$ cat sign.sec
untrusted comment: signify secret key
RWRCSwAAACrVwvFk3aEyZFmPQ3kkX8eVAXYt/DvCvS3JD4o2QgWw5dPT1GwM0/u9lgqB03XQqr5yJJx9f49kmX5vd6NBBHa0rk4e9XC8mVs6Q1jWMCmO6aQTjcLOHFhLr9Vxc+W+NSw=
$ signify -S -s sign.sec -m message.txt
passphrase: (z)
$ cat message.txt.sig
untrusted comment: verify with sign.pub
RWTJD4o2QgWw5Yl4xS5JBgxC4Zv+KnDXYfDJzpE6LU/FZbs5vHq2kVJ5E7ruNvUUL+sg1/OSOvnI6N6A57wpc2VrWwujA/m8mwU=
$ ls
message.txt     message.txt.sig sign.pub        sign.sec
$ signify -V -p sign.pub -m message.txt -x message.txt.sig
Signature Verified
$ minisign -V -p sign.pub -m message.txt -x message.txt.sig
message.txt.sig: Undefined error: 0
$ minisign -v
minisign 0.8

The other way around works okay. Signify can verify minisign signatures:

$ rm sign.pub sign.sec
$ minisign -G -p sign.pub -s sign.sec
Please enter a password to protect the secret key.

Password: (z)
Password (one more time):
Deriving a key from the password in order to encrypt the secret key... done

The secret key was saved as sign.sec - Keep it secret!
The public key was saved as sign.pub - That one can be public.

Files signed using this key pair can be verified with the following command:

minisign -Vm <file> -P RWSaFhePk+tC9vTTi+yeIO4Wl6ncKXi9+ic+Rj0nohuwNC/ZWZLgBoEx
$ cat sign.sec
untrusted comment: minisign encrypted secret key
RWRTY0Iy8Ih0p+rQl2n6xucscPJOdSK48PM+Un6uFrhB74CZR/oAAAACAAAAAAAAAEAAAAAAXEf+5XzHb5GZ0vHG9ToGyICcgqEyB6kj1FAX0o/rO5o6bjIPvf3dJYo9qbOUYhWCv+56u9rnEywSGLzL9+XFmp3B2wwh14cw2+VsVe6saQG/fjrI2/C3vjUbpX1pKzGhGO391w6IawQ=
$ minisign -S -s sign.sec -m message.txt
Password: (z)
Deriving a key from the password and decrypting the secret key... done
$ cat message.txt.minisig
untrusted comment: signature from minisign secret key
RWSaFhePk+tC9snG7mzd/58ED3RdUFmO3KkyR5K8Vx/4WJCkRqHKBtUAVe4zSkoG2TgDGAImnjKBmHChbbjAxoD+TaY81Owx6AE=
trusted comment: timestamp:1563858228   file:message.txt
D1HGUOIL0Qc9OqibpK7QwMO3crzhoUdaur25n1eyMBL2q4r0loThMZycevcN1bMOg61h6cA5+PuBY8kE6MxFAw==
$ minisign -V -p sign.pub -m message.txt -x message.txt.minisig
Signature and comment signature verified
Trusted comment: timestamp:1563858228   file:message.txt
$ signify -V -p sign.pub -m message.txt -x message.txt.minisig
Signature Verified

Just in case this is somehow system-specific, I'm on MacOS with minisign and signify installed from Homebrew.

$ brew info signify-osx
signify-osx: stable 1.4 (bottled), HEAD
Cryptographically sign and verify files
https://man.openbsd.org/signify.1
/usr/local/Cellar/signify-osx/1.4 (6 files, 174.8KB) *
  Poured from bottle on 2019-07-22 at 14:46:59
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/signify-osx.rb
==> Options
--HEAD
    Install HEAD version
==> Analytics
install: 28 (30 days), 59 (90 days), 221 (365 days)
install_on_request: 28 (30 days), 58 (90 days), 208 (365 days)
build_error: 0 (30 days)
$ brew info minisign
minisign: stable 0.8 (bottled)
Sign files & verify signatures. Works with signify in OpenBSD
https://jedisct1.github.io/minisign/
/usr/local/Cellar/minisign/0.8 (6 files, 38.1KB) *
  Poured from bottle on 2019-07-22 at 13:40:52
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/minisign.rb
==> Dependencies
Build: cmake ✔
Required: libsodium ✔
==> Analytics
install: 85 (30 days), 172 (90 days), 644 (365 days)
install_on_request: 63 (30 days), 116 (90 days), 420 (365 days)
build_error: 0 (30 days)

Also note that the size-limitation of signify also affects signature verification, so the “legacy switch” doesn’t make sense for large files (since you can’t verify with signify anyway).

Top comments (0)