I have a sample code in .NET C# which I need to convert to RUBY.
public static string Encrypt(string pstrText)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(pstrText);
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(secKey));
hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray =cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
I have tried using OPENSSL:CIPHER and got thus far -
def encrypt data
secret = "******************"
md5 = Digest::MD5.hexdigest(secret)
des = OpenSSL::Cipher::Cipher.new 'DES-EDE3'
des.encrypt
des.key = md5
update_value = des.update(data)
up_final = update_value + des.final
puts Base64.encode64(up_final).gsub(/\n/, "")
end
The results in C# and RUBY do not match. Where am I going wrong?
Related
I have a service named CryptoService which inherit the interface ICryptoService that consist of 2 method Crypto Decrypto function.
Encryption of a string is Working but the Decryption of hash result will return my key instead of the Decrypted string.
Here is my encryption code :
private string _salt = "*1234567890!##$%^&*()14344*";
private string Crypto(string text)
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Encoding.UTF8.GetBytes(_salt);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
My decryption code :
private string Decrypto(string text)
{
try
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Convert.FromBase64String(text);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
TripleDesProvider.Clear();
return Encoding.UTF8.GetString(resultArray);
//return Encoding.UTF8.GetString(resultArray);
}
catch
{
return string.Empty;
}
}
provided here the screenshot in action.
here are the references of my codes I found in the internet
https://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C
This cannot work. A hash, such as MD5, is one-way. You cannot get the original text from the hash value.
If your crypto service runs on the same machine, I suggest using the Data Protection class.
Your toEncryptArray in Encrypto gets the value _salt. You meant text.
So, good news, your decryption works.
when I try do decrypt my encrypted key I receive an error saying that it's wrong data / inaccurate data. Tried to search around for a while without any result. This is both the encryption code and decryption code. The indata is a MAC-Address for encryption, and indata for decryption is read from textfile.
public string encryptMAC(string indata)
{
byte[] resultCrypt;
UTF8Encoding utf8 = new UTF8Encoding();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
byte[] encrypt = utf8.GetBytes(indata);
try
{
ICryptoTransform encryptor = tdes.CreateEncryptor();
resultCrypt = encryptor.TransformFinalBlock(encrypt, 0, encrypt.Length);
}
finally
{
tdes.Clear();
}
return Convert.ToBase64String(resultCrypt);
}
public string decryptMAC(string indata)
{
byte[] resultDecrypt;
UTF8Encoding utf8 = new UTF8Encoding();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
byte[] decrypt = Convert.FromBase64String(indata);
try
{
ICryptoTransform decryptor = tdes.CreateDecryptor();
resultDecrypt = decryptor.TransformFinalBlock(decrypt, 0, decrypt.Length);
}
catch (CryptographicException ex)
{
Console.WriteLine(ex);
}
finally
{
tdes.Clear();
}
return utf8.GetString(decrypt);
}
TripleDESCryptoServiceProvider will generate a key for you. If you don't set it yourself or retrieve it during encryption, then you will not be able to decrypt the ciphertext.
I suggest that you add a key to your methods and use the same one for encryption and decryption:
public string encryptMAC(string indata, byte[] key)
{
byte[] resultCrypt;
UTF8Encoding utf8 = new UTF8Encoding();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
tdes.Key = key;
byte[] encrypt = utf8.GetBytes(indata);
try
{
ICryptoTransform encryptor = tdes.CreateEncryptor();
resultCrypt = encryptor.TransformFinalBlock(encrypt, 0, encrypt.Length);
}
finally
{
tdes.Clear();
}
return Convert.ToBase64String(resultCrypt);
}
public string decryptMAC(string indata, byte[] key)
{
byte[] resultDecrypt = new byte[0];
UTF8Encoding utf8 = new UTF8Encoding();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
tdes.Key = key;
byte[] decrypt = Convert.FromBase64String(indata);
try
{
ICryptoTransform decryptor = tdes.CreateDecryptor();
resultDecrypt = decryptor.TransformFinalBlock(decrypt, 0, decrypt.Length);
}
catch (CryptographicException ex)
{
Console.WriteLine(ex);
}
finally
{
tdes.Clear();
}
return utf8.GetString(resultDecrypt);
}
Keep in mind that DES has a small set of weak keys, so you should use TripleDESCryptoServiceProvider to generate a key for you which will filter out those weak keys. You can generate a valid key by (new TripleDESCryptoServiceProvider()).Key.
I am decrypting a message in C#, this message is encrypted in PHP using below code:-
public function __construct($sEncryptionKey)
{
$this->link = mcrypt_module_open('tripledes', '', 'ecb', '');
$this->sInitializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->link), MCRYPT_RAND);
$this->iKeySize = mcrypt_enc_get_key_size($this->link);
$sEncryptionKey = substr(md5($sEncryptionKey), 0, $this->iKeySize);
mcrypt_generic_init($this->link, $sEncryptionKey, $this->sInitializationVector);
}
public function encrypt($sDataToEncrypt)
{
return base64_encode(mcrypt_generic($this->link, $sDataToEncrypt));
}
And I am using below decryption function in c# for decryption:-
public string Decrypt(string toDecrypt, string key, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
{
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
var strValue = UTF8Encoding.UTF8.GetString(resultArray);
return UTF8Encoding.UTF8.GetString(resultArray);
}
I tried with few changes and getting below results:-
1.) PaddingMode.PKCS7 with no hashing = "Specified key is not a valid size for this algorithm."
2.) PaddingMode.PKCS7 with hashing = "Bad Data."
3.) PaddingMode.Zeros with no hashing = "Specified key is not a valid size for this algorithm."
4.) PaddingMode.Zeros with hashing = "�8�f����q6IGs�" some unknown characters
I think 4'th one will work, but not sure what I am doing wrong.
Found a solution, need to do changes in MD5 hashing, below are whole code if someone stuck in same situation :-
public string Decrypt(string toDecrypt, string key, bool useHashing)
{
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
string keyArrayStr = "";
if (useHashing)
{
MD5 md5 = MD5CryptoServiceProvider.Create();
byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(key));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataMd5.Length; i++)
sb.AppendFormat("{0:x2}", dataMd5[i]);
keyArrayStr = sb.ToString().Substring(0, tdes.Key.Length);
keyArray = UTF8Encoding.UTF8.GetBytes(keyArrayStr);
}
else
{
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
var strValue = UTF8Encoding.UTF8.GetString(resultArray);
return UTF8Encoding.UTF8.GetString(resultArray);
}
I am trying to understand and implement 3DES Encryption using C# that would be compatible with oracle dbms_obfuscation_toolkit.
I got help from below two location
https://javasight.wordpress.com/2008/08/24/net-encryption-and-oracle-decryption/
Different DES Encryption in Oracle and .NET
Unfortunately I'm unable to create an encrypted string compatible with below statement
select trim(dbms_obfuscation_toolkit.DESDecrypt(input_string=>utl_raw.cast_to_varchar2(hextoraw('EncryptedString')),key_string=>'MagicKey'))
from dual
public static string Encrypt(string toEncrypt)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
string iv = "0123456789ABCDEF";
string s = "4D616769634B6579";
keyArray = ASCIIEncoding.ASCII.GetBytes(s);
byte[] ivBytes = new byte[iv.Length];
ivBytes = StringUtilities.HexStringToByteArray(iv);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.IV = ivBytes;
tdes.Padding = PaddingMode.None;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock
(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return StringUtilities.ByteArrayToHexString(resultArray);
}
The key that I am using in C# Code is rawtohex('MagicKey') which translates to 4D616769634B6579
When I encrypt with C# I get arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BN
static void Main(string[] args)
{
Encoding byteEncoder = Encoding.Default;
String key = "ShHhd8a08JhJiho98ayslcjh";
String message = "Let us meet at 9 o'clock at the secret place.";
String encryption = Encrypt(message, key, false);
String decryption = Decrypt(encryption , key, false);
Console.WriteLine("Message: {0}", message);
Console.WriteLine("Encryption: {0}", encryption);
Console.WriteLine("Decryption: {0}", decryption);
}
public static string Encrypt(string toEncrypt, string key, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string toDecrypt, string key, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return UTF8Encoding.UTF8.GetString(resultArray);
}
When I encrypt with PHP I get: arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMVM+W/WFlksR
<?php
$key = "ShHhd8a08JhJiho98ayslcjh";
$input = "Let us meet at 9 o'clock at the secret place.";
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo base64_encode($encrypted_data);
?>
I don't know enough about cryptography to figure out why. Any ideas? Thanks.
Peter is right. PHP just pads with zeros, while you're using PKCS#7 in the C# code. Here's some code that should do it right:
function pkcs7_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
$input = pkcs7_pad("Let us meet at 9 o'clock at the secret place.", 16);
Alternatively, you should be able to put this in your C# code:
tdes.Padding = PaddingMode.Zeros;
and also have it work (albeit slightly less securely).
I don't know PHP, and neither have I analysed your C# code carefully, but as most of the encrypted string is the same maybe the padding of the data is the difference? Maybe PHP uses another mode than the PaddingMode.PKCS7 used in the C# code? (This would have been a comment if I could comment...)
As a side note: if you are using ECB then you do not need an IV. Actually, using ECB is most of the time a security hazard, so you really need to use something else, e.g. CBC, which uses an IV. The IV is a random, non-secret value with the same size than the cipher block size (8 bytes for 3DES). A new IV must be created for each message, and the decrypting party must know the IV that the encrypting party used. In practice, the IV is sent along with the encrypted message.