2013-12-17 6 views
7

Mam za zadanie zastąpienie starszego systemu java czymś, co uruchamia PHP.Zastępowanie JAVA z PHP dla szyfrowania PKCS5

Trochę utknąłem na zastąpieniu kryptografii java kodem PHP.

cipherAlgorythm = "PBEWithMD5AndDES";       
cipherTransformation = "PBEWithMD5AndDES/CBC/PKCS5Padding";  
PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(salt, iterations); 
SecretKeyFactory kf = SecretKeyFactory.getInstance(cipherAlgorythm); 
SecretKey key = kf.generateSecret(new javax.crypto.spec.PBEKeySpec(password.toCharArray())); 
Cipher encryptCipher = Cipher.getInstance(cipherTransformation); 
encryptCipher.init(Cipher.ENCRYPT_MODE, key, ps); 
byte[] output = encryptCipher.doFinal("This is a test string".getBytes("UTF-8")); 

wydaje się wnętrzności Java

W PHP robie

$hashed_key = pbkdf2('md5', $this->key, $this->salt, $this->reps , <GUESS 1>, TRUE); 
$output = mcrypt_encrypt(MCRYPT_DES, $hashed_key, "This is a test string", MCRYPT_MODE_CBC, <GUESS 2>); 

PBKDF2 jest od here.

So <GUESS 1> jest rozmiar klucza i <GUESS 2> jest IV . Grałem z nimi bezskutecznie. Czy ktoś ma sugestię co do takich wartości? O ile widzę, samo szyfrowanie powinno być przenośne, ale nie jestem pewien, co dzieje się w niektórych metodach Java.

Wygląda na to, że java tworzy gdzieś IV, ale nie rozumiem, jak i gdzie.

ZWIĄZANE

Decrypt (with PHP) a Java encryption (PBEWithMD5AndDES)

Odpowiedz

1

Oba istniejące odpowiedzi pomógł, ale będę pisać kompletne rozwiązanie tutaj.

Nie widziałem to udokumentowane wszędzie, ale po pobycie w implementacji tego programu szyfrującego znalazłem klucz jest pierwsze 8 bajtów zaszyfrowanej hash i IV jest ostatnim 8.

public function get_key_and_iv($key, $salt, $reps) { 
    $hash = $key . $salt; 
    for ($i = 0; $i< $reps; $i++) { 
     $hash = md5($hash, TRUE); 
    } 
    return str_split($hash,8); 
    } 

wydaje Zrób sztuczkę. Które zastępuje pbkdf2 w moim pytaniu, zaprzecza potrzebie <GUESS 1> i daje wartość dla <GUESS 2>

Potem zostałem złapany z problemem wyściełania, o którym wspomniał James Black i który udało się naprawić. Ostateczny kod to

list($hashed_key, $iv) = get_key_and_iv($key, $salt, $reps); 
// 8 is DES block size. 
$pad = 8 - (strlen($plaintext) % 8); 
$padded_string = $plaintext . str_repeat(chr($pad), $pad); 
return mcrypt_encrypt(MCRYPT_DES, $hashed_key, $padded_string, MCRYPT_MODE_CBC, $iv); 
1

Możesz zajrzeć do http://us3.php.net/manual/en/ref.mcrypt.php#69782, ale w zasadzie on realizowany DIY rozwiązanie padding:

function pkcs5_pad ($text, $blocksize) 
{ 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 

To może być najlepszym, ale jeśli spójrz na ten komentarz, jego sugestie, w jaki sposób sprawdzić, czy każdy krok jest poprawny, mogą ci się przydać.

https://stackoverflow.com/a/10201034/67566

Idealnie należy odejść od DES i ponieważ wyściółka będzie problem w PHP, dlaczego nie sprawdzić, czy można zmienić algorytm szyfrowania do czegoś mniej kłopotliwe i bardziej bezpieczny?

Aby pomóc Ci wyświetlić tę stronę: http://www.ietf.org/rfc/rfc4772.txt, gdzie zwięźle jest napisane, że DES jest podatny na ataki typu brute force, został więc przestarzały i zastąpiony przez AES.

1

Możesz również użyć hash_pbkdf2 PHP (5.5) function zamiast używać bibliotek PHP PBKDF2.

Według docs PHP domysłu 1 jest długością utworzony pochodzi klucz

długość

Długość łańcucha wyjściowego. Jeśli raw_output ma wartość TRUE, odpowiada ona długości bajtowej klucza pochodnego, jeśli raw_output wynosi FALSE, to odpowiada dwukrotnej długości bajtu uzyskanego klucza (jako każdy bajt klucza jest zwracany jako dwa heksy).

Jeśli zostanie podane 0, zostanie użyte całe wyjście dostarczonego algorytmu.

Może ten wynik post (what is an optimal Hash size in bytes?) jest dla Ciebie interesujący.

GUESS 2 lub IV to losowy wektor inicjalizacyjny używany do tworzenia unikatowej soli do generowania skrótu.

Możesz utworzyć IV z mycript_create_iv function.

Spójrz na całą próbkę w php.net

<?php 
$password = "password"; 
$iterations = 1000; 

// Generate a random IV using mcrypt_create_iv(), 
// openssl_random_pseudo_bytes() or another suitable source of randomness 
$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); 

$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20); 
echo $hash; 
?>