{"record":{"id":"57005158b2e2b9f4","repo":"passbolt/passbolt_api","slug":"could-not-use-the-key-to-encrypt","errorCode":null,"errorMessage":"Could not use the key to encrypt.","messagePattern":"Could not use the key to encrypt\\.","errorType":"exception","errorClass":"Cake\\Core\\Exception\\CakeException","httpStatus":null,"severity":"error","filePath":"src/Utility/OpenPGP/Backends/Gnupg.php","lineNumber":345,"sourceCode":"            $this->assertSignKey();\n            try {\n                /** @var string|false $encryptedText */\n                $encryptedText = $this->_gpg->encryptsign($text);\n            } catch (Exception $e) {\n                throw new CakeException($msg . ' ' . $e->getMessage(), null, $e);\n            }\n            if ($encryptedText === false) {\n                throw new CakeException($msg);\n            }\n            $this->clearSignKeys();\n        } else {\n            $msg = __('Could not use the key to encrypt.');\n            $this->assertEncryptKey();\n            try {\n                /** @var string|false $encryptedText */\n                $encryptedText = $this->_gpg->encrypt($text);\n            } catch (Exception $e) {\n                throw new CakeException($msg . ' ' . $e->getMessage(), null, $e);\n            }\n            if ($encryptedText === false) {\n                throw new CakeException($msg);\n            }\n        }\n        $this->clearEncryptKeys();\n\n        return $encryptedText;\n    }\n\n    /**\n     * Encrypt a text and sign it too\n     * Do not forget to add a key to encrypt and sign\n     *\n     * @param string $text plain text to be encrypted.\n     * @throws \\Cake\\Core\\Exception\\CakeException if no key was set to encrypt and optionally to sign\n     * @throws \\Cake\\Core\\Exception\\CakeException if there is an issue with the key to encrypt and optionally to sign\n     * @return string encrypted text","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/OpenPGP/Backends/Gnupg.php#L327-L363","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","solutions":["Check the exception's appended gnupg message to identify the offending key fingerprint","Verify the recipient public key is in the gpg keyring of the PHP process user: gpg --homedir <homedir> --list-keys <fingerprint>","(Re-)import the recipient public key via the backend's importServerKeyInKeyring or setEncryptKey with a valid fingerprint","Ensure the gnupg homedir (GNUPGHOME) exists, is owned by the web/CLI user, and has 700 permissions","Confirm the key is not expired/revoked and has the encryption usage capability"],"exampleFix":"// before\n$gpg->setEncryptKey($unknownFingerprint);\n$armored = $gpg->encrypt($text); // CakeException: Could not use the key to encrypt.\n// after\n$gpg->setEncryptKey($importedFingerprint); // fingerprint of a key present in the keyring\n$armored = $gpg->encrypt($text);","handlingStrategy":"try-catch","validationCode":"$fingerprint = $gpg->getEncryptKeyFingerprint();\nif (!$fingerprint || !in_array($fingerprint, shell_exec('gpg --list-keys --with-colons') ? [] : [], true)) { /* pre-check keyring */ }","typeGuard":null,"tryCatchPattern":"try {\n    $armored = $gpg->encrypt($text);\n} catch (CakeException $e) {\n    $this->log('Encryption failed: ' . $e->getMessage());\n    throw new RuntimeException('Recipient key unavailable for encryption.', 0, $e);\n}","preventionTips":["Import and trust recipient public keys before encrypting","Validate fingerprint format (40 hex chars) and existence in keyring at application bootstrap","Keep GNUPGHOME owned by the runtime user with 700 permissions","Monitor key expiry dates and re-issue keys before expiration"],"tags":["openpgp","encryption","gnupg","keyring"],"backgroundTag":"openpgp-encryption-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}