{"record":{"id":"6e38ca625f2f4c1a","repo":"lcobucci/jwt","slug":"sodiumexception-message","errorCode":null,"errorMessage":"<SodiumException message>","messagePattern":"<SodiumException message>","errorType":"exception","errorClass":"Lcobucci\\JWT\\Signer\\InvalidKeyProvided","httpStatus":null,"severity":"error","filePath":"src/Signer/Eddsa.php","lineNumber":24,"sourceCode":"use Lcobucci\\JWT\\Signer;\nuse SodiumException;\n\nuse function sodium_crypto_sign_detached;\nuse function sodium_crypto_sign_verify_detached;\n\nfinal readonly class Eddsa implements Signer\n{\n    public function algorithmId(): string\n    {\n        return 'EdDSA';\n    }\n\n    public function sign(string $payload, Key $key): string\n    {\n        try {\n            return sodium_crypto_sign_detached($payload, $key->contents());\n        } catch (SodiumException $sodiumException) {\n            throw new InvalidKeyProvided($sodiumException->getMessage(), 0, $sodiumException);\n        }\n    }\n\n    public function verify(string $expected, string $payload, Key $key): bool\n    {\n        try {\n            return sodium_crypto_sign_verify_detached($expected, $payload, $key->contents());\n        } catch (SodiumException $sodiumException) {\n            throw new InvalidKeyProvided($sodiumException->getMessage(), 0, $sodiumException);\n        }\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":37,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Signer/Eddsa.php#L6-L37","documentation":"This library wraps sodium_crypto_sign_detached (Ed25519 detached signing). If libsodium rejects the call it throws SodiumException, which Eddsa::sign catches and rethrows as InvalidKeyProvided with the original message and exception chained as previous. In practice it means the Key contents are not a valid Ed25519 secret key (wrong length/format) or the payload/key pair is unusable for signing.","triggerScenarios":"Calling Eddsa::sign($payload, $key) where $key->contents() is not exactly SODIUM_CRYPTO_SIGN_SECRETKEYBYTES (64) bytes of a valid Ed25519 secret key, or is an empty/garbage string; sodium also throws when the underlying key material cannot be used by sodium_crypto_sign_detached.","commonSituations":"Passing a base64/hex-encoded key without decoding it first; passing a public key or an Ed25519 seed alone instead of the full secret key; truncating or corrupting key files; mixing up signing and verification keys; using keys generated by another algorithm (e.g. HMAC or RSA keys).","solutions":["Inspect the SodiumException message (available via $e->getPrevious()) to see the exact libsodium complaint and fix the key material accordingly.","Ensure the key is a raw 64-byte Ed25519 secret key: if stored base64/hex-encoded, decode it (base64_decode / hex2bin) before constructing the Key.","Regenerate a valid key pair with sodium_crypto_sign_keypair() and use sodium_crypto_sign_secretkey() for signing and sodium_crypto_sign_publickey() for verification.","Verify you are not swapping secret and public keys between sign() and verify()."],"exampleFix":"// before\n$key = new Key(base64_encode($secretKey));\n$signature = $signer->sign($payload, $key); // InvalidKeyProvided\n// after\n$key = new Key(base64_decode($secretKey));\n$signature = $signer->sign($payload, $key);","handlingStrategy":"try-catch","validationCode":"if (strlen($key->contents()) !== SODIUM_CRYPTO_SIGN_SECRETKEYBYTES) {\n    throw new \\InvalidArgumentException('Ed25519 secret key must be ' . SODIUM_CRYPTO_SIGN_SECRETKEYBYTES . ' raw bytes');\n}","typeGuard":"function isValidEd25519SecretKey(string $key): bool\n{\n    return strlen($key) === SODIUM_CRYPTO_SIGN_SECRETKEYBYTES;\n}","tryCatchPattern":"try {\n    $signature = $signer->sign($payload, $key);\n} catch (Lcobucci\\JWT\\Signer\\InvalidKeyProvided $e) {\n    $root = $e->getPrevious(); // SodiumException with the libsodium detail\n    // log $root->getMessage() and fail the operation\n}","preventionTips":["Store and pass keys as raw binary; decode base64/hex exactly once at load time.","Use sodium_crypto_sign_secretkey() output directly rather than hand-assembled key material.","Keep signing and verification keys from the same keypair and label them clearly (secret vs public).","Unit-test sign() against a known RFC 8032 vector at boot to catch key-format regressions."],"tags":["eddsa","crypto","invalid-key","sodium"],"backgroundTag":"invalid-argument-value","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}