Vediamo. PKCS # 7 è descritto in RFC 5652 (Sintassi dei messaggi crittografici).
Lo schema di riempimento è indicato nella sezione 6.3. Content-encryption Process. In pratica dice: aggiungi quel numero di byte necessario per riempire la dimensione del blocco data (ma almeno uno), e ognuno di essi dovrebbe avere la lunghezza del padding come valore.
Quindi, guardando l'ultimo byte decrittografato sappiamo quanti byte rimuovere. (Si potrebbe anche verificare che abbiano tutti lo stesso valore.)
Ora potrei darvi una coppia di funzioni PHP, ma il mio PHP è un po 'arrugginito. Quindi fatelo anche voi (quindi sentitevi liberi di modificare la mia risposta per aggiungerla), o date un'occhiata allo user-contributed notes alla documentazione di mcrypt - alcuni di questi sono sul padding e forniscono un'implementazione del padding PKCS # 7.
Quindi, diamo un'occhiata sul first note there in dettaglio:
<?php
function encrypt($str, $key)
{
$block = mcrypt_get_block_size('des', 'ecb');
Questo ottiene la dimensione del blocco dell'algoritmo utilizzato. Nel tuo caso, useresti aes
o rijndael_128
invece di des
, suppongo (non l'ho provato). (Al contrario, si può semplicemente prendere 16
qui per AES, invece di invocare la funzione.)
$pad = $block - (strlen($str) % $block);
Questo calcola le dimensioni imbottitura. strlen($str)
è la lunghezza dei dati (in byte), % $block
fornisce il resto modulo $block
, ovvero il numero di byte di dati nell'ultimo blocco. $block - ...
fornisce quindi il numero di byte necessari per riempire quest'ultimo blocco (questo è ora un numero compreso tra 1
e $block
, incluso).
$str .= str_repeat(chr($pad), $pad);
str_repeat
produce una stringa costituita da una ripetizione della stessa stringa, qui una ripetizione del character given by$pad
, $pad
volte, cioè una stringa di lunghezza $pad
, riempito con $pad
. $str .= ...
aggiunge questa stringa di riempimento ai dati originali.
return mcrypt_encrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
Ecco la crittografia stessa. Utilizzare MCRYPT_RIJNDAEL_128
anziché MCRYPT_DES
.
}
Ora l'altra direzione:
function decrypt($str, $key)
{
$str = mcrypt_decrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
La decrittazione. (Ovviamente cambierai l'algoritmo, come sopra). $ str ora è la stringa decrittografata, incluso il padding.
$block = mcrypt_get_block_size('des', 'ecb');
Questa è di nuovo la dimensione del blocco. (Vedi sopra.)
$pad = ord($str[($len = strlen($str)) - 1]);
Questo sembra un po 'strano. Meglio scriverlo in più fasi:
$len = strlen($str);
$pad = ord($str[$len-1]);
$len
è ora la lunghezza della stringa imbottita, e $str[$len - 1]
è l'ultimo carattere di questa stringa. ord
lo converte in un numero. Quindi $pad
è il numero che abbiamo usato in precedenza come valore di riempimento per il padding, e questa è la lunghezza del padding.
return substr($str, 0, strlen($str) - $pad);
Così ora abbiamo tagliato gli ultimi $pad
byte dalla stringa. (Invece di strlen($str)
potremmo anche scrivere $len
qui: substr($str, 0, $len - $pad)
.).
}
?>
noti che invece di utilizzare substr($str, $len - $pad)
, si può anche scrivere substr($str, -$pad)
, come la funzione substr
in PHP ha una speciale trattamento per operandi negativi/argomenti, a contare dalla fine della stringa. (Non so se questo è più o meno efficiente di ottenere la lunghezza prima e calcolare l'indice manualmente.)
Come detto prima e annotato nel commento di rossum, invece di spogliare semplicemente l'imbottitura come fatto qui, si dovrebbe verificare che sia corretto - vale a dire guardare substr($str, $len - $pad)
e verificare che tutti i suoi byte siano chr($pad)
. Questo serve da controllo contro la corruzione (anche se questo controllo è più efficace se si utilizza una modalità di concatenamento anziché ECB e non è un sostituto per un MAC reale).
(E ancora, dire al vostro cliente che dovrebbero pensare di cambiare a una modalità più sicura di BCE.)
Solo una nota: Se si può cambiare, usare [un altro modo di BCE (è insicuro)] (http: //en.wikipedia. org/wiki/Block_cipher_modes_of_operation). –
@Paul No, non può cambiare, è ciò che dipende dal sistema del client. Qualche possibilità che tu possa guidarmi con l'imbottitura? –
Intendevo AES, risolto. –