Blog : How to implement common file encryption and decryption between c# and php
How to implement common file encryption and decryption between c# and php
Recently I got a opportunity to work with 2 different languages(c# and php) for file encryption and decryption.
But the problem is the above solution works for string encryption and decryption.When i try to implement the same for file, the file has been corrupted for docx,xlsx formats due to padding zeros.After little research, i have sorted out the issue.
Here is the code for PHP. You can also download the live samples attached in the bottom of this post
function Encrypt($source, $destination) {
$key="passwordDR0wSS@P6660juht";
$iv="password";
if (extension_loaded('mcrypt') === true)
{
if (is_file($source) === true)
{
$source = file_get_contents($source);
$encryptedSource=$this->TripleDesEncrypt($source,$key,$iv);
if (file_put_contents($destination,$encryptedSource, LOCK_EX) !== false)
{
return true;
}
return false;
}
return false;
}
return false;
}
function Decrypt($source, $destination) {
$key="passwordDR0wSS@P6660juht";
$iv="password";
if (extension_loaded('mcrypt') === true)
{
if (is_file($source) === true)
{
$source = file_get_contents($source);
$decryptedSource=self::TripleDesDecrypt($source,$key,$iv);
if (file_put_contents($destination,$decryptedSource, LOCK_EX) !== false)
{
return true;
}
echo "no read";
return false;
}
echo "no file";
return false;
}
echo "no mcrypt";
return false;
}
/*
Apply tripleDES algorthim for encryption, append "___EOT" to encrypted file ,
so that we can remove it while decrpytion also padding 0's
*/
function TripleDesEncrypt($buffer,$key,$iv) {
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
$buffer.='___EOT';
// get the amount of bytes to pad
$extra = 8 - (strlen($buffer) % 8);
// add the zero padding
if($extra > 0) {
for($i = 0; $i < $extra; $i++) {
$buffer .= '_';
}
}
mcrypt_generic_init($cipher, $key, $iv);
$result = mcrypt_generic($cipher, $buffer);
mcrypt_generic_deinit($cipher);
return base64_encode($result);
}
/*
Apply tripleDES algorthim for decryption, remove "___EOT" from encrypted file ,
so that we can get the real data.
*/
function TripleDesDecrypt($buffer,$key,$iv) {
$buffer= base64_decode($buffer);
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, $iv);
$result = mdecrypt_generic($cipher,$buffer);
$result=substr($result,0,strpos($result,'___EOT'));
mcrypt_generic_deinit($cipher);
return $result;
}
code for C#
private byte[] Encrypt(byte[] data)
{
string Key = "passwordDR0wSS@P6660juht";
string IV = "password";
string enc1 = Encoding.Default.GetString(data);
enc1 += "___EOT";
data = Encoding.Default.GetBytes(enc1);
byte[] key = Encoding.ASCII.GetBytes(Key);
byte[] iv = Encoding.ASCII.GetBytes(IV);
byte[] enc = new byte[0];
TripleDES tdes = TripleDES.Create();
tdes.IV = iv;
tdes.Key = key;
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform ict = tdes.CreateEncryptor();
enc = ict.TransformFinalBlock(data, 0, data.Length);
data = Encoding.UTF8.GetBytes(Convert.ToBase64String(enc));
return data;
}
private byte[] Decrypt(byte[] data)
{
string Key = "passwordDR0wSS@P6660juht";
string IV = "password";
byte[] enc = new byte[0];
byte[] key = Encoding.ASCII.GetBytes(Key);
byte[] iv = Encoding.ASCII.GetBytes(IV);
TripleDES tdes = TripleDES.Create();
tdes.IV = iv;
tdes.Key = key;
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform ict = tdes.CreateDecryptor();
data = Convert.FromBase64String(Encoding.UTF8.GetString(data));
enc = ict.TransformFinalBlock(data, 0, data.Length);
string enc1 = Encoding.Default.GetString(enc);
enc1 = enc1.Substring(0, enc1.IndexOf("___EOT"));
enc = Encoding.Default.GetBytes(enc1);
return enc;
}
private byte[] ReadFile(string path)
{
byte[] fileContents = null;
try
{
FileInfo ff = new FileInfo(path);
fileContents = new byte[ff.Length];
using (FileStream fr = ff.OpenRead())
{
fr.Read(fileContents, 0, Convert.ToInt32(ff.Length));
}
}
catch (Exception ex)
{
throw;
}
return fileContents;
}
private void WriteFile(string path, byte[] data)
{
FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
fileStream.Write(data, 0, data.Length);
fileStream.Close();
}