php / php/php-src

openssl_seal()/_open() is not able to handle gcm cipers, e.g. aes-256-gcm

Offen
#7,737 10 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Extension: openssl Feature Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

The following code:

<?php

const NUM_KEYS = 2;

for ($i = 0; $i < NUM_KEYS; $i++) {
  $keys[] = $key = openssl_pkey_new();
  $details = openssl_pkey_get_details($key);
  $pubKeys[] = $details['key'];
  $privKeys[] = openssl_pkey_get_private($key);
}

$data = 'Test Data String';

$ciphers = [
  'aes-256-ctr',
  'aes-256-gcm',
];

foreach ($ciphers as $cipherAlgo) {

  echo "*** TESTING $cipherAlgo ***" . PHP_EOL . PHP_EOL;
  $iv = \random_bytes(openssl_cipher_iv_length($cipherAlgo));
  $result = openssl_seal($data, $sealedData, $sealedKeys, $pubKeys, $cipherAlgo, $iv);

  echo "DATA  :   " . strlen($data) . ' ' . $data . PHP_EOL;
  echo "IV-LEN:   " . openssl_cipher_iv_length($cipherAlgo) . PHP_EOL;
  echo "IV    :   " . bin2hex($iv) . PHP_EOL;
  echo "ENC DATA: " . strlen($sealedData) . ' ' . bin2hex($sealedData) . PHP_EOL;
  echo "RESULT:   " . ($result ? 'true' : 'false') . PHP_EOL;
  echo PHP_EOL;

  // Try decrypt
  foreach ($keys as $i => $key) {
    $decrypted = null; // ;)
    $result = openssl_open($sealedData, $decrypted, $sealedKeys[$i], $key, $cipherAlgo, $iv);
    echo "OPEN:    " . $decrypted . PHP_EOL;
    echo "RESULT:  " . ($result ? 'true' : 'false') . PHP_EOL;

    $result = openssl_private_decrypt($sealedKeys[$i], $unsealedKey, $key);
    echo "UNSEAL:  " . bin2hex($unsealedKey) . PHP_EOL;
    echo "RESULT:  " . ($result ? 'true' : 'false') . PHP_EOL;
    echo "DECRYPT: " . openssl_decrypt($sealedData, $cipherAlgo, $unsealedKey, OPENSSL_RAW_DATA, $iv) . PHP_EOL;
  }

  echo PHP_EOL;
}

Resulted in this output:

$ ./openssl-seal-test.php
*** TESTING aes-256-ctr ***

DATA  :   16 Test Data String
IV-LEN:   16
IV    :   37ff67041864b987b8ec2dcd0879f55e
ENC DATA: 16 2a748aa6ae176caf59cf22868304d65a
RESULT:   true

OPEN:    Test Data String
RESULT:  true
UNSEAL:  8745e00bdf3d88bd1caa8ec0150a9b369eade92e57fc2d26ae283f224c66af14
RESULT:  true
DECRYPT: Test Data String
OPEN:    Test Data String
RESULT:  true
UNSEAL:  8745e00bdf3d88bd1caa8ec0150a9b369eade92e57fc2d26ae283f224c66af14
RESULT:  true
DECRYPT: Test Data String

*** TESTING aes-256-gcm ***

DATA  :   16 Test Data String
IV-LEN:   12
IV    :   033b1589f62bebbfffa3adda
ENC DATA: 16 a531f88fc51e373235c928cae1eb7c29
RESULT:   true

OPEN:    
RESULT:  false
UNSEAL:  600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT:  true
DECRYPT: 
OPEN:    
RESULT:  false
UNSEAL:  600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT:  true
DECRYPT: 

But I expected this output instead:

[...]
*** TESTING aes-256-gcm ***

DATA  :   16 Test Data String
IV-LEN:   12
IV    :   033b1589f62bebbfffa3adda
ENC DATA: 16 a531f88fc51e373235c928cae1eb7c29
RESULT:   true

OPEN:    Test Data String
RESULT:  true
UNSEAL:  600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT:  false
DECRYPT: 
OPEN:    Test Data String
RESULT:  true
UNSEAL:  600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT:  false
DECRYPT: 

The point is that the gcm-cipher need the authentication tag for decrypting the data. This however does not seem to be saved by the openssl_seal() function. I have also placed a question in the OpenSSL issue tracker: https://github.com/openssl/openssl/issues/17235

PHP Version

PHP 8.0.13 (cli) (built: Nov 27 2021 17:17:19) ( ZTS )

Operating System

Gentoo Linux 5.15.6, but should not matter

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere das bereitgestellte PHP-Skript und vergleiche die Pfade aes-256-ctr und aes-256-gcm über openssl_seal() und openssl_open(). Lies die Implementierungen dieser Einstiegspunkte und das verknüpfte OpenSSL-Problem, um zu bestimmen, wie der Authentifizierungstag behandelt wird. Als erledigt gilt die Aufgabe, wenn das GCM-Verhalten und der Fehlermodus durch das erwartete API-Verhalten des Projekts abgedeckt sind.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, php
Bereich
backend-api-design, cryptography, security
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.