Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Jwsign Laravel Package

yakeing/php_jwsign

yakeing/php_jwsign is a lightweight PHP library for creating and verifying JSON Web Signature (JWS) tokens. It provides straightforward APIs for signing payloads, validating signatures, and adding JWS-based authentication or data integrity checks to PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you are installing first. Despite the name, yakeing/php_jwsign is not a JWS (RFC 7515) implementation. It is a small OpenSSL wrapper for encrypting/decrypting strings and is described by its author only as "a class of data encryption and decryption." Do not drop it at a JWT verification boundary or expect token interoperability with firebase/php-jwt or any compliant JOSE library.

The package is archived (last release 2019-08-06, 0 dependents, 35 stars). It still installs, but nothing upstream is maintained. Treat it as you would a copy-pasted helper class: usable if the crypto primitives it wraps are what you need, but you own the security review.

Minimal setup:

  1. Confirm the PHP version constraint in composer.json against your app; a 2019 package will often cap below PHP 8.x. If Composer refuses, you will need --ignore-platform-reqs in a scratch project to test, which is a strong signal to stop.
  2. composer require yakeing/php_jwsign
  3. Read the repository README and any examples/ directory before writing integration code. There is no Laravel documentation and the API surface is a handful of methods; the README is the only accurate reference for constructor arguments and return types.
  4. Verify ext-openssl is enabled and that the class loads:
$r = new ReflectionClass(\Yakeing\JwSign\JwSign::class); // adjust namespace from README

First use case worth wiring up: encrypting a small opaque payload before it leaves your trust boundary—an API credential stored for a third party, or a signed webhook body. That is the shape this class is built for. Anything involving long-lived, high-value secrets should go through Laravel's own Crypt facade or defuse/php-encryption instead, both of which are maintained and have authenticated-encryption defaults.

Implementation Patterns

Bind it, do not new it. Because the object holds key material, register a singleton in a service provider so a single instance per request is reused and key loading happens once.

// app/Providers/JwSignServiceProvider.php
public function register(): void
{
    $this->app->singleton(JwSign::class, function () {
        $key = config('jwsign.private_key_path');
        return new JwSign(file_get_contents(storage_path($key)));
    });
}

Register manually in config/app.php under providers—there is no extra.laravel auto-discovery in a package of this vintage.

Keep keys in storage/, never in config/. Point the config file at a path under storage/app/keys/, resolve it with storage_path(), and add that directory to .gitignore. Ship a .env variable (JWSIGN_PRIVATE_KEY_PATH) so each environment gets its own key.

Wrap it in your own interface. You want the rest of the app coupled to App\Contracts\PayloadCipher, not to an archived vendor class. This is the single most valuable pattern here—it makes swapping to phpseclib or Crypt a one-file change later.

interface PayloadCipher {
    public function seal(string $plaintext): string;
    public function open(string $ciphertext): string;
}

Eloquent cast for encrypted columns. A custom cast keeps controllers clean and centralizes the format:

class SealedCast implements CastsAttributes
{
    public function get($model, $key, $value, $attributes) {
        return $value === null ? null : app(PayloadCipher::class)->open($value);
    }
    public function set($model, $key, $value, $attributes) {
        return [$key => $value === null ? null : app(PayloadCipher::class)->seal($value)];
    }
}

Size the backing column as TEXT, not VARCHAR(255)—RSA ciphertext plus base64 framing routinely blows past 255 bytes.

Webhook signing pattern. Resolve the cipher in a middleware, seal the JSON body, and send the ciphertext in a dedicated header. On the inbound side, verify before your controller sees the payload, and compare with hash_equals() if you add your own HMAC layer on top.

Testing. Bind a stub implementation of PayloadCipher in TestCase::setUp() for feature tests, and keep one small integration test that exercises the real class with a throwaway 2048-bit keypair generated in the test fixture. This keeps the crypto out of the 95% of tests that do not care about it.

Gotchas and Tips

  • Archived means no security advisories. You will not be notified if a flaw is found. If this sits anywhere near authentication or payment data, get a second opinion or use a maintained library.
  • Naming trap. Engineers will assume php_jwsign speaks JOSE. It does not. Every consumer needs to know the wire format is bespoke—document it in your API spec so nobody tries to validate these blobs with a JWT library.
  • MPL-2.0 is file-level copyleft. Using it unmodified as a dependency is fine. If you patch the vendor source directly (which you may be forced to do if PHP compatibility breaks), those modified files must be published under MPL. Prefer subclassing or wrapping over editing, and if you must edit, fork it into your own repository rather than committing changes into vendor/.
  • RSA payload length is hard-capped by key size minus padding overhead. A 2048-bit key with PKCS#1 v1.5 padding gives you roughly 245 bytes of plaintext. If you are sealing JSON documents, either generate a symmetric key per payload and wrap that, or use a 4096-bit key—and test with your largest realistic payload early, because this failure appears in production, not in the happy-path test.
  • Padding mode matters for interop. PKCS#1 v1.5 versus OAEP is not interchangeable. If the counterparty is .NET or Java, confirm which scheme they expect before you encode the first message.
  • Base64 handling is the usual bug source. Decide once whether the class returns raw bytes or base64, and normalize at your adapter boundary. Binary ciphertext stored in a utf8mb4 column will corrupt silently.
  • Error behavior across PHP versions. Code from 2019 often returns false and emits a warning rather than throwing. Wrap calls in an adapter that converts failure to an exception; otherwise a decrypt failure looks like an empty string in your logs.
  • Rotate with a key id prefix. Store ciphertext as v1:<base64> so you can introduce a new keypair and decrypt old rows during a migration window. Without this, rotation is a data-loss event.
  • Serialization. Never put the cipher instance on a queued job or in a session. Resolve it from the container inside the job.
  • Reasonable alternatives to weigh honestly: Laravel's Crypt facade (symmetric, authenticated, zero integration cost), phpseclib (maintained RSA/OpenSSL work), firebase/php-jwt or web-token/jwt-framework if you actually need standards-compliant signing. Pick this package only if something specific—an existing wire format, a partner's reference implementation—requires it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums