php / php/php-src

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

Abierto
#7,737 10 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Extension: openssl Feature Status: Verified
Lenguaje dominante
C
Estrellas
40.4k
Forks
8.2k
Merge medio
2 d 13 h
PR fusionados (30 d)
96

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Reproduce el script PHP proporcionado y compara las rutas aes-256-ctr y aes-256-gcm mediante openssl_seal() y openssl_open(). Lee las implementaciones de esos puntos de entrada y el issue vinculado de OpenSSL para determinar cómo se gestiona la etiqueta de autenticación. Se considera terminado cuando el comportamiento de GCM y el modo de fallo están cubiertos por el comportamiento esperado de la API del proyecto.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
c, php
Área
backend-api-design, cryptography, security
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.