Chiffrer, déchiffrer et signer des données avec OpenSSL, RSA et PHP

J’ai eu récemment affaire avec un webservice utilisant des données chiffrées avec des clés privées – clés publiques. Le web service était codé dans un langage autre que PHP et utilisait des clés publiques au format XML pour déchiffrer les données.

L’ennui est que PHP ne gère pas les clés au format XML, j’ai donc du créer une solution pour palier à ce problème.

Les solutions actuelles étant à mon sens trop compliquées pour un besoin simple, je me suis créé ma propre classe pour le chiffrement de ces données.

Cette classe offre une interface de programmation « simple » pour chiffrer, déchiffrer et signer des données.

 

 

 

<?php

use SimpleXMLElement;

class RSAKeyPair
{

    protected $privateKeyAsString;
    protected $publicKeyAsString;
    protected $details;
    private $resource;

    public static function fromPrivateString($string)
    {
        $rsa = new self();
        $rsa->loadPrivateKey($string);

        return $rsa;
    }

    public static function generate($bits = 4096, $type = OPENSSL_KEYTYPE_RSA)
    {
        //Crée une nouvelle clé privée et publique
        $new_key_pair = openssl_pkey_new(array(
            "private_key_bits" => $bits,
            "private_key_type" => $type,
        ));

        openssl_pkey_export($new_key_pair, $private_key_pem);
        openssl_free_key($new_key_pair);

        $obj = new self;
        $obj->loadPrivateKey($private_key_pem);
        return $obj;
    }

    public function exportPrivateAsPEM()
    {
        return $this->privateKeyAsString;
    }

    public function loadPrivateKey($string)
    {
        $this->resource = openssl_get_privatekey($string);
        $details = openssl_pkey_get_details($this->resource);
        $public_key_pem = $details['key'];

        $this->privateKeyAsString = $string;
        $this->publicKeyAsString = $public_key_pem;
        $this->details = $details;
    }

    public function signDataWithSHA256($data)
    {
        openssl_sign($data, $signed, $this->resource, OPENSSL_ALGO_SHA256);
        return $signed;
    }

    public function decrypt($data)
    {
        openssl_private_decrypt($data, $decrypted, $this->resource);
        return $decrypted;
    }

    public function exportPublicAsXML()
    {
        $rsa = $this->details['rsa'];
        $xml = new SimpleXMLElement("<RSAKeyValue/>"); // Use <RSAKeyPair/> for XKMS 2.0
        $map = ["n" => "Modulus", "e" => "Exponent"];

        foreach ($map as $key => $element) {
            $xml->addChild($element, base64_encode($rsa[$key]));
        }
        return $xml->asXML();
    }

    public function exportPrivateAsXML()
    {
        $rsa = $this->details['rsa'];
        $xml = new SimpleXMLElement("<RSAKeyValue/>");
        $map = ["n" => "Modulus", "e" => "Exponent", "p" => "P", "q" => "Q",
            "dmp1" => "DP", "dmq1" => "DQ", "iqmp" => "InverseQ", "d" => "D",];
        foreach ($map as $key => $element) {
            $xml->addChild($element, base64_encode($rsa[$key]));
        }
        return $xml->asXML();
    }
}

 

Chiffrer, déchiffrer et signer des données avec OpenSSL, RSA et PHP

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *