passbolt/passbolt_api · error · Cake\Core\Exception\CakeException

Could not use the key to encrypt.

Error message

Could not use the key to encrypt.

What it means

Wraps a failure of the underlying gnupg extension's encrypt() call when encrypting with the recipient public key(s) set via setEncryptKey. The library first asserts an encrypt key is present, then lets gnupg do the work; if gnupg throws (or the source region shows the companion false-return branch), it rethrows as a CakeException prefixed with 'Could not use the key to encrypt.' plus the gnupg error message.

Solutions

  1. Check the exception's appended gnupg message to identify the offending key fingerprint
  2. Verify the recipient public key is in the gpg keyring of the PHP process user: gpg --homedir <homedir> --list-keys <fingerprint>
  3. (Re-)import the recipient public key via the backend's importServerKeyInKeyring or setEncryptKey with a valid fingerprint
  4. Ensure the gnupg homedir (GNUPGHOME) exists, is owned by the web/CLI user, and has 700 permissions
  5. Confirm the key is not expired/revoked and has the encryption usage capability

Example fix

// before
$gpg->setEncryptKey($unknownFingerprint);
$armored = $gpg->encrypt($text); // CakeException: Could not use the key to encrypt.
// after
$gpg->setEncryptKey($importedFingerprint); // fingerprint of a key present in the keyring
$armored = $gpg->encrypt($text);
Defensive patterns

Strategy: try-catch

Validate before calling

$fingerprint = $gpg->getEncryptKeyFingerprint();
if (!$fingerprint || !in_array($fingerprint, shell_exec('gpg --list-keys --with-colons') ? [] : [], true)) { /* pre-check keyring */ }

Try / catch

try {
    $armored = $gpg->encrypt($text);
} catch (CakeException $e) {
    $this->log('Encryption failed: ' . $e->getMessage());
    throw new RuntimeException('Recipient key unavailable for encryption.', 0, $e);
}

Prevention

When it happens

Trigger: Calling encrypt($text) (or encryptSign via encrypt) when the configured encrypt-key fingerprint does not correspond to a key actually present/trusted in the keyring, the key is expired/revoked, or gpgme/gnupg rejects the recipient key during $this->_gpg->encrypt($text).

Common situations: Server keyring missing the recipient public key after a container rebuild; wrong passbolt.gpg.serverKey fingerprint config; unimported user public key; gnupg homedir permission issues (wrong owner on ~/.gnupg); key expired or without encryption capability (sign-only key).

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/57005158b2e2b9f4. Report an issue: GitHub.

Appendix: source

Thrown at src/Utility/OpenPGP/Backends/Gnupg.php:345

            $this->assertSignKey();
            try {
                /** @var string|false $encryptedText */
                $encryptedText = $this->_gpg->encryptsign($text);
            } catch (Exception $e) {
                throw new CakeException($msg . ' ' . $e->getMessage(), null, $e);
            }
            if ($encryptedText === false) {
                throw new CakeException($msg);
            }
            $this->clearSignKeys();
        } else {
            $msg = __('Could not use the key to encrypt.');
            $this->assertEncryptKey();
            try {
                /** @var string|false $encryptedText */
                $encryptedText = $this->_gpg->encrypt($text);
            } catch (Exception $e) {
                throw new CakeException($msg . ' ' . $e->getMessage(), null, $e);
            }
            if ($encryptedText === false) {
                throw new CakeException($msg);
            }
        }
        $this->clearEncryptKeys();

        return $encryptedText;
    }

    /**
     * Encrypt a text and sign it too
     * Do not forget to add a key to encrypt and sign
     *
     * @param string $text plain text to be encrypted.
     * @throws \Cake\Core\Exception\CakeException if no key was set to encrypt and optionally to sign
     * @throws \Cake\Core\Exception\CakeException if there is an issue with the key to encrypt and optionally to sign
     * @return string encrypted text

View on GitHub (pinned to 31c1bbc10f)