Replacing JAVA with PHP for PKCS5 encryption

前端 未结 3 1386
抹茶落季
抹茶落季 2021-02-09 12:16

I have been tasked with replacing a legacy java system with something which runs PHP.

I am getting a little stuck on replacing the java cryptography with PHP code.

相关标签:
3条回答
  • 2021-02-09 12:45

    You can use hash_pbkdf2 PHP (5.5) function too instead of using PBKDF2 PHP libraries.

    According to PHP docs the GUESS 1 is the length of the created derived key

    length

    The length of the output string. If raw_output is TRUE this corresponds to the byte-length of the derived key, if raw_output is FALSE this corresponds to twice the byte-length of the derived key (as every byte of the key is returned as two hexits).

    If 0 is passed, the entire output of the supplied algorithm is used.

    Maybe this post (what is an optimal Hash size in bytes?) result interesting for you.

    GUESS 2 or IV is a random initialization vector used to create an unique salt to generate the hash.

    You can create the IV with mycript_create_iv function.

    Take a look at the complete sample in 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;
    ?>
    
    0 讨论(0)
  • 2021-02-09 12:51

    Both existing answers helped, but I'll post the complete solution here.

    I have not seen it documented anywhere but after looking at implementations for this encryption scheme I found the key is the first 8 bytes of the encrypted hash and the IV is the last 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);
      }
    

    seems to do the trick. Which replaces pbkdf2 in my question, negates the need for <GUESS 1> and gives a value for <GUESS 2>

    Then I got caught with the padding problem which James Black mentioned and managed to fix. So final code is

    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);
    
    0 讨论(0)
  • 2021-02-09 13:06

    You may want to look at http://us3.php.net/manual/en/ref.mcrypt.php#69782, but basically he implemented a DIY padding solution:

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

    That may be your best bet, but if you look at this comment, his suggestions on how to verify that each step is correct may be useful for you.

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

    Ideally you should move away from DES and since this padding is going to be a problem in PHP, why not see if you can change the encryption algorithm to something less troublesome and more secure?

    To help you can show this page: http://www.ietf.org/rfc/rfc4772.txt, where it is succinctly expressed that DES is susceptible to brute force attacks, so has been deprecated and replaced with AES.

    0 讨论(0)
提交回复
热议问题