1

I have this C# Class (Below). The receiver uses this to encrypt/decrypt my messages. I am trying to use phpseclib to encrypt/decrypt and I cannot encrypt/decrypt successfully for the receiver. What is the correct implementation with phpseclib

using System; using System.IO; using System.Security.Cryptography; public class EncDec { public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV) { MemoryStream ms = new MemoryStream(); Rijndael alg = Rijndael.Create(); alg.Key = Key; alg.IV = IV; CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(clearData, 0, clearData.Length); cs.Close(); byte[] encryptedData = ms.ToArray(); return encryptedData; } public static string Encrypt(string clearText, string Password) { byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText); new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16)); return Convert.ToBase64String(encryptedData); } public static byte[] Encrypt(byte[] clearData, string Password) { PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16)); } public static void Encrypt(string fileIn, string fileOut, string Password) { FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read); FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write); PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); Rijndael alg = Rijndael.Create(); alg.Key = pdb.GetBytes(32); alg.IV = pdb.GetBytes(16); CryptoStream cs = new CryptoStream(fsOut, alg.CreateEncryptor(), CryptoStreamMode.Write); int bufferLen = 4096; byte[] buffer = new byte[bufferLen]; int bytesRead; do { bytesRead = fsIn.Read(buffer, 0, bufferLen); cs.Write(buffer, 0, bytesRead); } while (bytesRead != 0); cs.Close(); fsIn.Close(); } public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV) { MemoryStream ms = new MemoryStream(); Rijndael alg = Rijndael.Create(); alg.Key = Key; alg.IV = IV; CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(cipherData, 0, cipherData.Length); cs.Close(); byte[] decryptedData = ms.ToArray(); return decryptedData; } public static string Decrypt(string cipherText, string Password) { byte[] cipherBytes = Convert.FromBase64String(cipherText); PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); byte[] decryptedData = Decrypt(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16)); return System.Text.Encoding.Unicode.GetString(decryptedData); } public static byte[] Decrypt(byte[] cipherData, string Password) { PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16)); } public static void Decrypt(string fileIn, string fileOut, string Password) { FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read); FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write); PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); Rijndael alg = Rijndael.Create(); alg.Key = pdb.GetBytes(32); alg.IV = pdb.GetBytes(16); CryptoStream cs = new CryptoStream(fsOut, alg.CreateDecryptor(), CryptoStreamMode.Write); int bufferLen = 4096; byte[] buffer = new byte[bufferLen]; int bytesRead; do { bytesRead = fsIn.Read(buffer, 0, bufferLen); cs.Write(buffer, 0, bytesRead); } while (bytesRead != 0); cs.Close(); // this will also close the unrelying fsOut stream fsIn.Close(); } } 

This is an phpseclib example

 $rijndael = new \phpscelib\Crypt\Rijndael(); $rijndael->setKey($encryption_password); $clear_text = $rijndael->decrypt($cipher_text); $cipher_text = $rijndael->encrypt($clear_text); 
1
  • It's likely you are missing the IV on the php side. Also, if you are deriving Rijndael keys from a password, make sure to use the same algorithm with the same salt. Commented Jun 22, 2017 at 7:58

1 Answer 1

1

Two (or three) critical issues:

  • You are not setting the IV on the php side.
  • You derive a key from a password in your c# code. For your php code, you don't (you are using the password as a key directly).
  • You encode the cipher bytes using Base64 in c#. The php library doesn't seem to do that although I could be wrong with that.

Security issues:

  • You are using a fixed salt for your PasswordDeriveBytes. Consider generating a cryptographically random salt and prepend that to your ciphertext. If you want to know why, there are plenty of good answers here.
  • Using a plaintext password/phrase directly for encryption (like in your php code) is considered insecure. Encryption keys should be random-ish. The output of a password hash algorithm is okay.
Sign up to request clarification or add additional context in comments.

1 Comment

Let me try out your suggestions.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.