Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

AES En/Decryption and moving from phpseclib 2 to 3#1974

Answeredbyterrafrost
splitbrain asked this question inQ&A
Discussion options

I used to have the following code for encrypting/decrypting in phpseclib 2:

functionauth_encrypt($data,$secret){$iv =random_bytes(16);$cipher =newAES();$cipher->setPassword($secret);return$cipher->encrypt($iv .$data);}functionauth_decrypt($ciphertext,$secret){$iv =substr($ciphertext,0,16);$cipher =newAES();$cipher->setPassword($secret);$cipher->setIV($iv);return$cipher->decrypt(substr($ciphertext,16));}

When trying to port that code to version 3 I came up with the following:

functionauth_encrypt($data,$secret){$iv =random_bytes(16);$cipher =newAES('cbc');$cipher->setPassword($secret);$cipher->setIV($iv);return$cipher->encrypt($iv .$data);}functionauth_decrypt($ciphertext,$secret){$iv =substr($ciphertext,0,16);$cipher =newAES('cbc');$cipher->setPassword($secret);$cipher->setIV($iv);return$cipher->decrypt(substr($ciphertext,16));}

The new code works, as far as it is possible to decrypt what has been encrypted with it. However what does not work is decrypting any cipher that has been encrypted with the old version 2 code.

The error I receive when trying to decode old ciphers is:

phpseclib3\Exception\BadDecryptionException: The ciphertext has an invalid padding length (229) compared to the block size (16)

I strongly suspect it's something about the IV handling. I did not write the original code and I am not familiar enough with AES to really understand what's going on.

Could anyone help me port the original code into new version 3 compatible code?

You must be logged in to vote

Try this:

$cipher->setPassword($secret, 'pbkdf2', 'sha1', 'phpseclib');

phpseclib v3 changed the salt fromphpseclib tophpseclib/salt.

Replies: 2 comments 2 replies

Comment options

phpseclib v2 null padded the ciphertext. You can simulate it thusly:

$len =strlen($ciphertext);$block_size =$cipher->getBlockLengthInBytes();$ciphertext =str_pad($ciphertext,$len + ($block_size -$len %$block_size) %$block_size,chr(0));

The fact that your original code is relying on that means that the last few bytes of the original code aren't getting decrypted correctly.

You must be logged in to vote
1 reply
@splitbrain
Comment options

Thanks a lot for your reply! Adding this to myauth_decrypt() method seems to make no difference. I still get the invalid padding length error.

I wasn't sure when to pad, before or after removing the IV. So I tried both versions:

functionauth_decrypt($ciphertext,$secret){$iv     =substr($ciphertext,0,16);$cipher =newAES('cbc');$cipher->setPassword($secret);$cipher->setIV($iv);$ciphertext =substr($ciphertext,16);$len =strlen($ciphertext);$block_size =$cipher->getBlockLengthInBytes();$ciphertext =str_pad($ciphertext,$len + ($block_size -$len %$block_size) %$block_size,chr(0));return$cipher->decrypt($ciphertext);}

and

functionauth_decrypt($ciphertext,$secret){$iv     =substr($ciphertext,0,16);$cipher =newAES('cbc');$cipher->setPassword($secret);$cipher->setIV($iv);$len =strlen($ciphertext);$block_size =$cipher->getBlockLengthInBytes();$ciphertext =str_pad($ciphertext,$len + ($block_size -$len %$block_size) %$block_size,chr(0));$ciphertext =substr($ciphertext,16);return$cipher->decrypt($ciphertext);}

Interestingly (to me) it has no influence on a encrypt-decrypt run using phpseclib3 only but both fail the same way with the samepadding length (229) error.

FYI, here's my test cases:

functiontestDeEncrypt()    {$data ="OnA28asdfäakgß*+!\"+*";$secret ="oeaf1öasdöflk§";$this->assertEquals($data,auth_decrypt(auth_encrypt($data,$secret),$secret));    }/**     * Try to decode a known secret. This one has been created with phpseclib Version 2     */functiontestCompatibility()    {$secret ='secret';$plain ='This is secret';$crypt ='837e9943623a34fe340e89024c28f4e9be13bbcacdd139801ef16a27bffa7714';$this->assertEquals($plain,auth_decrypt(hex2bin($crypt),$secret));    }

Again, I'm not fluent in encryption stuff, so if you tell me the way it was done in the original code has always been wrong and it should be done differently to be safe, I am open to take that advice and eschew the backwards compatibility. But ideally I would like to have it work again.

Comment options

Try this:

$cipher->setPassword($secret, 'pbkdf2', 'sha1', 'phpseclib');

phpseclib v3 changed the salt fromphpseclib tophpseclib/salt.

You must be logged in to vote
1 reply
@splitbrain
Comment options

That was it! Thank you very much for your help!

Answer selected bysplitbrain
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
Q&A
Labels
None yet
2 participants
@splitbrain@terrafrost

[8]ページ先頭

©2009-2025 Movatter.jp