5

I currently have an encrypt and decrypt for 3DES (des-ede-cbc) in PHP as follows:

php > $key = '0000000000000000';
php > $iv = '00000000';
php > $plaintext = '1234567812345678';
php > $ciphertext = openssl_encrypt($plaintext, 'des-ede-cbc', $key, 0, $iv);
php > echo $ciphertext;
LEvEJf9CI+5VTVNeIjARNamKH+PNTx2P

php > $plaintext = openssl_decrypt($ciphertext, 'des-ede-cbc', $key, 0, $iv);
php > echo $plaintext;
1234567812345678

I need to be able to take the ciphertext and decrypt it in python. The closest I've found is pycrypto: https://gist.github.com/komuw/83ddf9b4ae8f995f15af

My attempt:

>>> key = '0000000000000000'
>>> iv = '00000000'
>>> cipher_decrypt = DES3.new(key, DES3.MODE_CBC, iv)
>>> plaintext = cipher_decrypt.decrypt('LEvEJf9CI+5VTVNeIjARNamKH+PNTx2P')
>>> plaintext
b']v\xdf\xa7\xf7\xc0()\x08\xdf\xcb`4\xa7\x10\x9e\xaf\x8c\xb6\x00+_\xb3?2\x1d\\\x08\x01\xfa\xf2\x99'

I'm not sure what it's doing differently. It's 3DES with mode CBC. I'm not exactly sure what the ede part means, but I can't seem to find anything to emulate that exact openssl mode.

Version info:
Python 3.6.5
PHP 7.1.3

Cruncher
  • 7,641
  • 1
  • 31
  • 65
  • 1
    IIRC, the "EDE" just stands for "encrypt-decrypt-encrypt"; it just means you're using an encrypt-decrypt-encrypt 3DES rather than one of the other much-rarer (and less-useful) ways of tripling DES. – abarnert Apr 05 '18 at 18:33
  • Yep: [see here](https://stackoverflow.com/questions/41825573/wich-key-length-has-des-ede-cbc-cipher) for details. (I'm pretty sure none of the details are relevant here—you're almost surely using TDEA 3-key EDE in both cases—but it might be worth reading even if I'm right about that.) – abarnert Apr 05 '18 at 18:34
  • The cipher text is encoded in base64, `plaintext = cipher_decrypt.decrypt(base64.decodebytes(b'LEvEJf9CI+5VTVNeIjARNamKH+PNTx2P'))` returns `b'1234567812345678\x08\x08\x08\x08\x08\x08\x08\x08'`. Does that answer your question? – Jacques Gaudin Apr 05 '18 at 19:23
  • 1
    des-ede-cbc is two key version (2TDEA) and the Python 2TDEA mode is implied by key size 128 bits (or 16 bytes) – Anssi May 04 '22 at 08:57

1 Answers1

2

The string you get from PHP is base64 encoded.

from Crypto.Cipher import DES3
from base64 import decodebytes

key = b'0000000000000000'
iv = b'00000000'

cipher_decrypt = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = cipher_decrypt.decrypt(decodebytes(b'LEvEJf9CI+5VTVNeIjARNamKH+PNTx2P'))

print(plaintext.decode("utf-8"))

>>>1234567812345678
Jacques Gaudin
  • 15,779
  • 10
  • 54
  • 75