PHP AES Decryption working Encryption NOT

给你一囗甜甜゛ 提交于 2020-01-02 07:16:13

问题


So, I have 3 Pieces out of 4 working, iOS Encrypt-Decrypt from this Link And I am able to Decrypt the data Encrypted from iOS I am having trouble Encrypting on PHP side. When I do echo Encryption code. PHP prints something like F>HFl8aR what does it mean ?

SALTKEY = 'a16byteslongkey!';

Decryption Code: Working

     $result =  mcrypt_decrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                               base64_decode($text), 'ecb');
     $pad_char = ord(substr($result, -1));
     return substr($result, 0, strlen($result) - $pad_char);

Encryption Code : Not Working

     $result =  mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                               base64_encode($text), 'ecb');
     $pad_char = ord(substr($result, -1));
     return substr($result, 0, strlen($result) - $pad_char);
  • Results on iOS : Text = "Hello"
    Encryption = "7opqbb7sEVNoXplyQv/X8g=="
    Decryption of (7opqbb7sEVNoXplyQv/X8g==) = "Hello"

  • Results on PHP : Text = "7opqbb7sEVNoXplyQv/X8g=="
    Decryption = "Hello"
    Encryption of (Hello) = "_~TPn~p3MF?"


回答1:


I think its fairly obvious that the IOS encryption is giving a 7-bit result (looks like base64 encoded) while the PHP is giving an 8-bit representation.

You don't seem to have got the hang of reversing the operation.

The decryption is performed by base64_decodeing the input, then applying mcrypt_decrypt. It follows that to perform this in reverse, you'd need to first mcrypt_encrypt, and then base64_encode.

i.e.

 $result =  base64_encode(
          mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 
                (SALTKEY . str_repeat(chr(0x00), 16)), 
                $text, 'ecb'));



回答2:


Your encryption looks very bogus:

 $result =  mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                           base64_encode($text), 'ecb');
 $pad_char = ord(substr($result, -1));
 return substr($result, 0, strlen($result) - $pad_char);

You encode the text with base64, then encrypt it, and then and then try to remove padding?

Instead, you have to

  • add padding (if the encryption function doesn't already do this),
  • encrypt
  • then base-64-encode the result (if you want to have it somehow readable by humans or transmit over a non-binary-safe channel).

This could look like this:

$padded = pad($text);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                       $padded, 'ecb');
$result = base64_encode($encrypted);

(Have a look at the user-contributed notes at the mcrypt_encrypt documentation for an example on how to create the padding.)

Of course, there are some more things to remark:

  • Don't ever use ECB-mode, if you don't know anything about cryptography. It is an unsafe mode of operation. Use CBC-mode (with a random initialization vector, which is sent with the data).

  • You create your key by padding the SALTKEY with zeros. This makes your key in effect weaker than necessary. (Having a key hard-coded in the code is a bad idea anyways.) Supply a full 128-bit key, or derive one from a password using salt and a key derivation function (like PBKDF-2) with a high iteration count.

  • Your decryption function should also check that the padding is valid (i.e. consists of identical bytes), not simply removing it.

  • You should also use a message authentication code (MAC) with your message, to avoid some chosen-ciphertext attacks which allow decrypting a message.




回答3:


see my post here: PHP iOS AES Encryption

I keep reposting this as I see the same question over and over.


I just got through this same sort of project. I used the library you referenced in "also considered..."

Here is some example code to decrypt with php:

$iv2 = '';
for($i=0;$i<16;$i++){
    $iv2 .= "\0";   
}
$plain_text_CBC = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_text, MCRYPT_MODE_CBC, $iv2);
var_dump($plain_text_CBC);

Make sure your keys are both 256-bit (32 characters, I have not yet had any encoding issues, but if you do, remember that you are encrypting bytes, not characters). Note that 128 in MCRYPT_RIJNDAEL_128 is the block size and not the key size, while in the method AES256DecryptWithKey, 256 is a reference to the key size, while the block size is 128. AES256DecryptWithKey runs in CBC mode, but has a null initialization vector (iv).

CBC means that each block depends on the last block, and so it uses a pre-set, usually random, "block -1" called the IV

ECB means that each block is encrypted in the same way, hence it reveals when two blocks in the same message are the same. The library mentioned does not use it, so I mentioned it just for contrast.

The use of a zero iv (0000000000000000 in bytes) is considered insecure, but it does provide you with some additional security (but one might still be able to tell if the fist 16 characters of your plain text were the same each time). To fix this you would have to create an NSData *iv variable for the IV and modify the CCcrypt argument of NSData+AESCrypt.m to add [iv bytes] for the iv parameter (I have not yet tested this code), and you would need to store this iv and pass it to the php along with you message. But first I would test and have everything working with a zero iv.



来源:https://stackoverflow.com/questions/8179308/php-aes-decryption-working-encryption-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!