-2

I'm trying to encrypt a plaintext using DES algorithm in PHP.
I managed to code a working example in C#:

String plaintext = "1y7wpc4iddseyrwez1lor8ow3297t.pd0bfl";
String pass = "rpsxi.t.rjsmklexarygfqyrrkhwdjh";
byte[] bytesPlain = Encoding.UTF8.GetBytes(plaintext);
byte[] bytesPass = Encoding.UTF8.GetBytes(pass).Take(8).ToArray();
DESCryptoServiceProvider p = new DESCryptoServiceProvider();
p.Mode = CipherMode.ECB;
ICryptoTransform t = p.CreateEncryptor(bytesPass, bytesPass);
CryptoStreamMode m = CryptoStreamMode.Write;
MemoryStream stream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(stream, t, m);
cryptoStream.Write(bytesPlain, 0, bytesPlain.Length);
cryptoStream.FlushFinalBlock();
byte[] encBytesPlain = new byte[stream.Length];
stream.Position = 0;
stream.Read(encBytesPlain, 0, encBytesPlain.Length);
string encrypted = Convert.ToBase64String(encBytesPlain);
System.Diagnostics.Debug.WriteLine(encrypted);

plaintext = 1y7wpc4iddseyrwez1lor8ow3297t.pd0bfl
password = rpsxi.t.rjsmklexarygfqyrrkhwdjh
(only the first 8 bytes of the password are used to encrypt the message).

Anyway when I try to code a PHP version, using the crypt function or also this class I found on github https://github.com/phpseclib/phpseclib-php5/blob/master/phpseclib/Crypt/DES.php, i don't get the same result as the C# one.

I'm completely sure that the C# code works fine but I really don't know how to make a working version in PHP to get the same result in Base64.

Edit1: I already knew that DES isn't secure anymore but I need to use it in a web page just for learning purposes, also the way that C# code was written is completely right because I needed to follow some instructions and get that exactly result.

  • any reason to use DES? – Navjot Singh May 03 '19 at 12:06
  • 1
    If you use DES for anything other than learning, I would strongly suggest you choose another algorithm. – LLJ97 May 03 '19 at 12:09
  • 1
    The C# code is absolutely *not* right. You are using a 48 bit key, but DES uses 56 bit keys. You must never re-use an IV for the same key. Consider using 3DES instead of DES. 56 bit is considered a much too small key space nowadays. It can be brute-forced within hours. And finally, ECB is about the worst block mode you can pick. – Peter May 03 '19 at 12:18
  • BTW, why do you not use openssl? It is already built into PHP, it supports DES without any problems and I find it easy to use. – LLJ97 May 03 '19 at 12:24
  • If you want to learn, read PKCS#5: Password Based Encryption (PBE) - but note that even that standard is aging. – Maarten Bodewes May 03 '19 at 22:15

2 Answers2

1

DES is a deprecated encryption standard and you should not use it for anything else than learning purposes. AES would probably be the better choice if you're planning on using this to encrypt sensitive data.

Other than that since I haven't coded PHP in a while, but still wanted to contribute, I fixed up your existing C# code a little:

var plainText = "1y7wpc4iddseyrwez1lor8ow3297t.pd0bfl";
var password = "rpsxi.t.rjsmklexarygfqyrrkhwdjh";
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
var passwordBytes = Encoding.UTF8.GetBytes(password).Take(8).ToArray();

var des = new DESCryptoServiceProvider
{
    Mode = CipherMode.CBC, // don't use ECB as your CipherMode
    Padding = PaddingMode.PKCS7,
    Key = passwordBytes
};

des.GenerateIV(); // work with a unique IV for each operation

string encrypted = null;
using (var desEncryptor = des.CreateEncryptor())
{
    var resultStream = new MemoryStream();
    using (var cryptoStream = new CryptoStream(resultStream, desEncryptor, CryptoStreamMode.Write))
    {
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
    }

    encrypted = Convert.ToBase64String(resultStream.ToArray());
}

This is still not secure and as I said in the beginning, if security is critical for the application you're building you shouldn't use this. This answer is not supposed to make your code secure, just to point out some flaws in your usage of C# Streams and general coding guidelines.

For the PHP part this answer could work with the updated code I posted. You just have to extract the IV from the des object via des.IV and use it in your PHP script for the same functionality.

It's also worth noting that the used function mcrypt_encrypt is deprecated in newer versions of PHP, which brings me back to the first sentence of my answer: You should probably stop using DES altogether!

Tobias Tengler
  • 6,848
  • 4
  • 20
  • 34
1

Please do not use DES any more, as it is not considered secure anymore. Instead try using AES.

Also note that the php crypt function does not encrypt by default, but only creates a hash value using DES, which is not the same as encrypting.

Source: https://www.w3schools.com/php/func_string_crypt.asp