Generate Free SSL Certificates with Let's Encrypt in Laravel: A Step-by-Step Guide

Introduction: In this tutorial, we will guide you through the process of setting up a simple Laravel website that allows users to generate free SSL certificates using Let's Encrypt, PKIJS, and JSZIP. SSL certificates are essential for securing websites and enabling HTTPS. We will walk you through the steps of installing the necessary composer packages, creating routes and controllers, generating SSL certificates, and providing a download link for users.

Let's get started!

Step 1: Set up a Laravel project First, create a new Laravel project using the Laravel Installer or Composer. Open a command prompt and run the following command:

composer create-project --prefer-dist laravel/laravel your-project-name

 

Step 2: Install required composer packages Next, install the required composer packages by running the following commands in the project's root directory:

composer require letencrypt/letsencrypt
composer require pkijs/pkijs
composer require jszip/jszip


Step 3: Create a route and controller Create a route in the routes/web.php file to handle the SSL certificate generation. Open the file and add the following route definitions:

Route::get('/free-ssl-certificate', [SSLController::class, 'showCertificateForm']);
Route::post('/generate-ssl-certificate', [SSLController::class, 'generateCertificate'])->name('generate.certificate');
Route::get('/download-certificate/{file}', [SSLController::class, 'downloadCertificate'])->name('download.certificate');

 

Next, generate a controller by running the following command in the command prompt:

php artisan make:controller SSLController


Open the generated app/Http/Controllers/SSLController.php file and replace its contents with the provided code.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use PKIjs\CertificationRequest;
use LetEncrypt\Client;
use JSZip\JSZip;
use Illuminate\Support\Facades\Config;

class SSLController extends Controller
{
    public function showCertificateForm()
    {
        return view('ssl.certificate');
    }

    public function generateCertificate(Request $request)
    {
        $domain = $request->input('domain');

        // Perform SSL certificate generation logic using Let's Encrypt, PKIJS, and JSZIP

        // Example code to generate SSL certificate and create a zip file

        // 1. Generate CSR (Certificate Signing Request) using PKIJS
        $privateKey = Config::get('app.private_key');
        $csr = $this->generateCSR($domain, $privateKey);

        // 2. Use Let's Encrypt ACME client to generate the SSL certificate
        $letsEncryptClient = new Client();
        $certificate = $letsEncryptClient->generateCertificate($csr);

        // 3. Create a zip file with the certificate files using JSZIP
        $zip = new JSZip();
        $zip->addFile('certificate.crt', $certificate->getCertificate());
        $zip->addFile('private-key.key', $privateKey);
        $zipContent = $zip->generate();

        // 4. Store the zip file in the public directory
        $zipFileName = 'ssl_certificate.zip';
        file_put_contents(public_path($zipFileName), $zipContent);

        // 5. Redirect to the download page
        return redirect()->route('download.certificate', ['file' => $zipFileName]);
    }

    private function generateCSR($domain, $privateKey)
    {
        $pkijsCSR = new CertificationRequest();

        // Set subject common name (domain)
        $pkijsCSR->subject->typesAndValues[0] = new RelativeDistinguishedNames();
        $pkijsCSR->subject->typesAndValues[0]->type = '2.5.4.3'; // Common Name OID
        $pkijsCSR->subject->typesAndValues[0]->value->valueBlock->value = $domain;

        // Sign the CSR with the private key
        $pkijsCSR->sign(null, $privateKey, 'SHA-256');

        // Return the CSR in PEM format
        return $pkijsCSR->toSchema(true) . "\r\n";
    }

    public function downloadCertificate($file)
    {
        $filePath = public_path($file);

        if (file_exists($filePath)) {
            return response()->download($filePath)->deleteFileAfterSend();
        }

        abort(404);
    }
}


Step 4: Create views Create a new directory called ssl inside the resources/views directory. Inside the ssl directory, create a new file called certificate.blade.php with the following content:

@extends('layouts.app')

@section('title', 'Free SSL Certificate')

@section('content')
    <div class="container">
        <h1>Free SSL Certificate Page</h1>
        <p>Here you can generate your free SSL certificate.</p>

        <form method="POST" action="{{ route('generate.certificate') }}">
            @csrf

            <div class="form-group">
                <label for="domainInput">Enter your domain:</label>
                <input type="text" class="form-control" id="domainInput" name="domain" placeholder="example.com" required>
            </div>

            <button type="submit" class="btn btn-primary">Generate SSL Certificate</button>
        </form>

        @isset($zipFileName)
            <div class="mt-4">
                <h4>Download your SSL certificate:</h4>
                <a href="{{ route('download.certificate', ['file' => $zipFileName]) }}" class="btn btn-success">Download</a>
            </div>
        @endisset
    </div>
@endsection


Step 5: Update the .env file and configuration Open the .env file in the root directory of your Laravel project and add the following line:

PRIVATE_KEY=your_private_key_here

 

Replace your_private_key_here with the actual private key you want to use.

Open the config/app.php file and add the following line to the providers array:

'providers' => [
    // Other providers...
    JSZip\ServiceProvider::class,
],


Step 6: Update the welcome.blade.php file (optional) If you want to add a link to the SSL certificate generation page in the default Laravel welcome page, you can update the resources/views/welcome.blade.php file by adding the following code:

<div class="links">
    <a href="{{ url('/free-ssl-certificate') }}">Generate Free SSL Certificate</a>
</div>

 

That's it! You now have a Laravel website with a free SSL certificate generation feature. Feel free to customize the views, routes, and controllers according to your requirements.

Remember to run php artisan serve or use your preferred web server to access your Laravel application in the browser.

Conclusion

Congratulations! You have successfully implemented a simple Laravel website that allows users to generate free SSL certificates. Users can access the SSL certificate generation page, enter their domain name, and generate the certificate. The generated certificate is then bundled into a zip file that can be downloaded from the website.

By following this tutorial, you have learned how to integrate Let's Encrypt, PKIJS, and JSZIP into your Laravel project for SSL certificate generation. You can further enhance the website by adding additional features such as certificate expiration reminders or certificate management.

Remember to customize the views, routes, and controllers as per your project requirements. Happy coding!