Weave Code
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

Jwk To Pem Laravel Package

codercat/jwk-to-pem

Convert RSA JSON Web Keys (JWK) to PEM public keys in PHP. Simple API via JWKConverter->toPEM() for turning JWK arrays into PEM strings, useful for verifying JWT signatures. Note: currently supports RSA keys only.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require codercat/jwk-to-pem
    

    Add to composer.json if using Laravel’s autoloader (handled automatically via Composer).

  2. First Use Case: Convert a JWK (e.g., from an OAuth provider or API response) to PEM for use with Laravel’s openssl_* functions or libraries like firebase/php-jwt or league/oauth2-server.

    use CoderCat\JWKToPEM\JWKConverter;
    
    $converter = new JWKConverter();
    $jwk = json_decode(file_get_contents('path/to/jwk.json'), true);
    $pem = $converter->toPEM($jwk);
    
  3. Where to Look First:


Implementation Patterns

Core Workflow

  1. Fetch JWK: Retrieve JWK from an external source (e.g., OAuth provider’s JWKS endpoint) or static config.

    $jwks = json_decode(file_get_contents('https://example.com/.well-known/jwks.json'), true);
    
  2. Convert to PEM: Loop through JWKs (if multiple) and convert each to PEM. Cache results if the JWKS endpoint is static.

    $converter = new JWKConverter();
    $pems = collect($jwks['keys'])->map(fn($jwk) => $converter->toPEM($jwk));
    
  3. Use PEM:

    • Laravel HTTP Clients: Attach PEM to requests for client certificate auth.
      $client = new \GuzzleHttp\Client([
          'cert' => $pem,
      ]);
      
    • JWT Validation: Use PEM with firebase/php-jwt or league/oauth2-server.
      $jwt = new \Firebase\JWT\JWT();
      $decoded = $jwt->decode($token, $pem, ['RS256']);
      
  4. Integration with Laravel Services:

    • Service Provider: Bind the converter to the container for dependency injection.
      $this->app->singleton(JWKConverter::class, fn() => new JWKConverter());
      
    • Config: Store JWKS endpoint in config/services.php and fetch/convert in a service class.

Advanced Patterns

  • Caching: Cache PEM outputs if the JWKS endpoint is static (e.g., using Laravel’s cache).

    $pem = cache()->remember("jwk_{$jwk['kid']}_pem", now()->addHours(1), fn() =>
        $converter->toPEM($jwk)
    );
    
  • Dynamic JWKS Endpoints: Use Laravel’s Http client to fetch JWKS dynamically and convert on-demand.

    $jwks = Http::get('https://provider.com/.well-known/jwks.json')->json();
    $pems = collect($jwks['keys'])->map(fn($jwk) => $converter->toPEM($jwk))->toArray();
    
  • Testing: Mock the converter in tests to avoid external dependencies.

    $mockConverter = Mockery::mock(JWKConverter::class);
    $mockConverter->shouldReceive('toPEM')->andReturn('mock-pem');
    $this->app->instance(JWKConverter::class, $mockConverter);
    

Gotchas and Tips

Pitfalls

  1. RSA-Only Limitation: The package only supports RSA keys. Attempting to convert EC or other key types will throw an exception.

    • Workaround: Use a different library (e.g., web-token/jwt-framework) for non-RSA keys or pre-convert JWKs to PEM externally.
  2. Malformed JWKs: Missing or invalid fields (e.g., n, e for RSA) will cause failures. Validate JWKs before conversion:

    if (!isset($jwk['kty'], $jwk['n'], $jwk['e'])) {
        throw new \InvalidArgumentException('Invalid RSA JWK');
    }
    
  3. PEM Formatting: The output includes \r\n line endings. Replace with \n if needed for specific use cases (e.g., some APIs expect Unix line endings).

    $pem = str_replace("\r\n", "\n", $converter->toPEM($jwk));
    
  4. Deprecated Methods: Older versions had multipleToPEM() (renamed to toPEM() in v1.0). Ensure your code uses the current method.

Debugging Tips

  1. Exception Handling: Wrap conversion in a try-catch to handle invalid JWKs gracefully:

    try {
        $pem = $converter->toPEM($jwk);
    } catch (\Exception $e) {
        \Log::error("JWK conversion failed: " . $e->getMessage());
        throw new \RuntimeException('Failed to convert JWK to PEM');
    }
    
  2. Logging: Log JWK inputs for debugging:

    \Log::debug('Converting JWK', ['jwk' => $jwk]);
    
  3. Validation: Use json_schema to validate JWKs before conversion:

    composer require zendframework/zend-json-schema
    
    $validator = new \Zend\JsonSchema\Validator();
    $schema = json_decode(file_get_contents(__DIR__.'/rsa-jwk-schema.json'), true);
    $validator->validate($jwk, $schema);
    

Extension Points

  1. Custom PEM Headers: Override the default BEGIN PUBLIC KEY/END PUBLIC KEY headers by extending JWKConverter:

    class CustomJWKConverter extends JWKConverter {
        protected function getHeader(): string {
            return "-----BEGIN CUSTOM KEY-----";
        }
        protected function getFooter(): string {
            return "-----END CUSTOM KEY-----";
        }
    }
    
  2. Support for Private Keys: The package outputs public keys only. To support private keys, extend the class to handle d, p, q, etc. fields (requires additional cryptographic logic).

  3. Batch Processing: For large JWKS endpoints, process keys in chunks to avoid memory issues:

    $chunkedJwks = array_chunk($jwks['keys'], 100);
    foreach ($chunkedJwks as $chunk) {
        $pems = array_map([$converter, 'toPEM'], $chunk);
        // Store or use $pems
    }
    

Performance

  • Avoid Re-Conversion: Cache PEM outputs if the JWKS endpoint is static (e.g., using Laravel’s cache or Redis).
  • Lazy Loading: Convert JWKs to PEM only when needed (e.g., during JWT validation) rather than upfront.
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours