PHP & C# compatible Rijndael managed CBC mode, 256 bit encryption/decryption - c#

This is my very first attempt at cryptography and I am having trouble with porting the encryption from PHP to C#.
I had searched the internet for a working solution to my problem but everything I have tried does not work. I am getting different results between the two languages.
In PHP I have the following code:
function encrypt($Key, $strToEncrypt){
$md5Key = md5(pack("H*", $Key));
$md5Iv = md5($Key);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding = $block - (strlen($strToEncrypt) % $block);
$strToEncrypt .= str_repeat(chr($padding), $padding);
$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $md5Key, $strToEncrypt, MCRYPT_MODE_CBC, $md5Iv);
$enc2 = base64_encode($enc);
return $enc2;
}
and in C# the following code:
public string Encrypt(string strToEncrypt)
{
string ret;
var pKey = PackH(_appkey);
var md5Key = CalcMd5(pKey);
var iv = CalcMd5(_appkey);
var enc =Encoding.UTF8;
var eIv = enc.GetBytes(iv);
var eKey = enc.GetBytes(md5Key);
using (var rij = new RijndaelManaged { BlockSize = 256, KeySize = 256, IV = eIv, Key = eKey, Mode = CipherMode.CBC, Padding = PaddingMode.Zeros})
using (var memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, rij.CreateEncryptor(eKey, eIv), CryptoStreamMode.Write))
{
using (var sw = new StreamWriter(cryptoStream))
{
sw.Write(strToEncrypt);
}
ret = Convert.ToBase64String(memoryStream.ToArray());
}
return ret;
}
The C# Pack function:
protected byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
var bytes = new byte[hex.Length / 2];
for (var i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
And the C# CalcMd5 function:
protected string CalcMd5(string textToEnc)
{
var sB = new StringBuilder();
using (var mdHash = MD5.Create())
{
var cHash = mdHash.ComputeHash(Encoding.UTF8.GetBytes(textToEnc));
foreach (byte t in cHash)
{
sB.Append(t.ToString("x2"));
}
}
return sB.ToString();
}
I have another CalcMd5 function that takes in a byte[] (it is like the one above but does not have the GetBytes part).
The keys and the string that needs encrypting are the same both in PHP and C#:
The Key: "24acd2fcc7b20b8bd33ff45176f03061a09b729487e10d2dd38ab917" and
The string that I want to encode: "110114135AB96637711100"
In C# the result of the function is:"LHTqpxCJrONmbDdUFHyUZZUVf94z1RmSXWo85/wyEew=" while in PHP is: "5MkCjfs0vp2HSKdY5XPUAuV68YsrP31Q+ddZsd5p7Sc=".
I have tried modifying the padding mode in C#, also tried different methods found on the stackoverflow site but none of them works.
I have checked and the final key and Iv that are passed to the mcrypt function and RijndaelManaged function are the same and both have 32 byte size.
The oddly part is that the decryption functions are working very well (it is working to decrypt the PHP encrypted string with C# function and the other war around C# encrypted string is decrypted with the PHP function).
Could it be a problem with the encoding? Or maybe the padding? Or is there something else that I have overlooked?

The problem seems to be your padding, on PHP-side you are manually doing PKCS7-Padding:
$padding = $block - (strlen($strToEncrypt) % $block);
$strToEncrypt .= str_repeat(chr($padding), $padding);
And on C#-side you are using:
Padding = PaddingMode.Zeros
To fix this you could either modify the PHP-code by removing the above mentioned two lines since mcrypt() does automatically do ZeroBytePadding for you.
Or you could change the padding in C# to:
Padding = PaddingMode.PKCS7

Related

PHP encryption not compatible with .NET/C# decryption (AES-256/CBC)

when I try to encrypt using openssl_encrypt PHP I get square spaces at the end decrypted data which is shown in attached image
My API response is getting failure due to getting extra characters during decryption done by .NET side..
How can i resolve this issue please help
C#
public static string Decrypt(String encryptedText, String VendorKey, String Token)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(VendorKey,Token)));
}
private static byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateDecryptor()
.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey + Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
public static string Encrypt(String plainText, String VendorKey, String Token)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(VendorKey, Token)));
}
private static byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey + Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
So can help me to resolve this issue
When using the sample data you provided, encryption with the .NET code:
string vendorKey = "0123456789012345";
string token = "012345";
string pt = #"{""prospectNo"":""SL1000000"",""paymentRequestDateFrom"":""2020-05-28"",""paymentRequestDateTo"":""2020-06-02"",""merchantTransactionId"":""7"",""callerReferenceNo"":""3""}";
string ct = Encrypt(pt, vendorKey, token);
Console.WriteLine(ct);
returns the following ciphertext:
g163a7jXmZKjH1J3RjC7xkPn5+PJWY6wTX9BgxiTY8hkYjsqImlCuvXOtZgUrrfLnwLy1QGUk6iylc/sInV/XJ9sypJ93tCvjRoj4s4RWGKTqUk3bY31JTM6QuYVclw4zNvyq2WUBCc+EMGGYtn5dBAvqiYdTqrJJTae67EZfgc4Fw5ormmf0rCYXQ2mn7mc1Jdg8v2r3LK9FYiwLEbhOA==
The PHP code below:
<?php
$cipher = "AES-256-CBC";
$array = json_encode(array(
"prospectNo"=> "SL1000000",
"paymentRequestDateFrom"=>"2020-05-28",
"paymentRequestDateTo"=>"2020-06-02",
"merchantTransactionId"=> "7",
"callerReferenceNo"=>"3"
)
);
$token = "012345";
$vendorKey = "0123456789012345";
$key = substr(str_pad($vendorKey . $token, 32, "\0"), 0, 32);
$iv = substr(str_pad($vendorKey, 16, "\0"), 0, 16);
$encrypted_data = openssl_encrypt(zeroPad($array, 16), $cipher, $key, OPENSSL_ZERO_PADDING, $iv);
print($encrypted_data . "\n");
function zeroPad($text, $bs) {
$pad = ($bs - strlen($text) % $bs) % $bs;
return ($pad > 0) ? $text . str_repeat("\0", $pad) : $text;
}
?>
gives the same ciphertext and is thus the PHP counterpart you are looking for, i.e. under the premise that the API can process the data encrypted by the .NET code, it must also process the data encrypted by the PHP code.
As expected, this ciphertext is decrypted into the correct plaintext by the .NET code. The hex encoded plaintext also reveals that the .NET code does not remove the padding bytes (note the 8 0x00 bytes at the end):
string vendorKey = "0123456789012345";
string token = "012345";
string ct = "g163a7jXmZKjH1J3RjC7xkPn5+PJWY6wTX9BgxiTY8hkYjsqImlCuvXOtZgUrrfLnwLy1QGUk6iylc/sInV/XJ9sypJ93tCvjRoj4s4RWGKTqUk3bY31JTM6QuYVclw4zNvyq2WUBCc+EMGGYtn5dBAvqiYdTqrJJTae67EZfgc4Fw5ormmf0rCYXQ2mn7mc1Jdg8v2r3LK9FYiwLEbhOA==";
string dt = Decrypt(ct, vendorKey, token);
Console.WriteLine("Plaintext: " + dt);
Console.WriteLine("Plaintext, hex: " + Convert.ToHexString(Encoding.UTF8.GetBytes(dt)));
with the output:
Plaintext: {"prospectNo":"SL1000000","paymentRequestDateFrom":"2020-05-28","paymentRequestDateTo":"2020-06-02","merchantTransactionId":"7","callerReferenceNo":"3"}
Plaintext, hex: 7B2270726F73706563744E6F223A22534C31303030303030222C227061796D656E74526571756573744461746546726F6D223A22323032302D30352D3238222C227061796D656E745265717565737444617465546F223A22323032302D30362D3032222C226D65726368616E745472616E73616374696F6E4964223A2237222C2263616C6C65725265666572656E63654E6F223A2233227D0000000000000000
The PHP code posted in this answer differs from your original PHP code essentially only in a more general derivation of $key and $iv (but this makes no difference for the vendorKey used here) and the padding. The original PHP code applied the default PKCS#7 padding used by openssl_encrypt(), while the current PHP code applies Zero padding.
Specifically, for the current plaintext, this means that the original PHP code padded with 0x0808080808080808, while the current PHP code pads with 0x0000000000000000. Since the .NET code does not remove the padding, the padding bytes are still present even when using the current PHP code (just with different values).

c# Bouncy Castle Blowfish Decryption - Pad block corrupted

I am trying to decrypt a blowfish encrypted string with Bouncycastle in C#.
I am able to easily encrypt and decrypt my own string but, unfortunately, I have to decrypt a string that is generated by another system.
I AM able to recreate that same string with C# / Bouncycastle using the following but I have yet to decrypt it successfully.
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
...
static readonly Encoding Encoding = Encoding.UTF8;
public string BlowfishEncrypt(string strValue, string key)
{
try
{
BlowfishEngine engine = new BlowfishEngine();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(engine);
KeyParameter keyBytes = new KeyParameter(Encoding.GetBytes(key));
cipher.Init(true, keyBytes);
byte[] inB = Encoding.GetBytes(strValue);
byte[] outB = new byte[cipher.GetOutputSize(inB.Length)];
int len1 = cipher.ProcessBytes(inB, 0, inB.Length, outB, 0);
cipher.DoFinal(outB, len1);
return BitConverter.ToString(outB).Replace("-", "");
}
catch (Exception)
{
return "";
}
}
Below is what I have for decryption at the moment. The line that fails with error "pad block corrupted" is cipher.DoFinal(out2, len2);
public string BlowfishDecrypt(string name, string keyString)
{
BlowfishEngine engine = new BlowfishEngine();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(engine);
StringBuilder result = new StringBuilder();
cipher.Init(false, new KeyParameter(Encoding.GetBytes(keyString)));
byte[] out1 = Convert.FromBase64String(name);
byte[] out2 = new byte[cipher.GetOutputSize(out1.Length)];
int len2 = cipher.ProcessBytes(out1, 0, out1.Length, out2, 0);
cipher.DoFinal(out2, len2); //Pad block corrupted error happens here
String s2 = BitConverter.ToString(out2);
for (int i = 0; i < s2.Length; i++) {
char c = s2[i];
if (c != 0) {
result.Append(c.ToString());
}
}
return result.ToString();
}
Any idea what I might be doing wrong in BlowfishDecrypt()?
Note:
I converted the above (encrypt and decrypt) from a bouncycastle Java example I found somewhere; the encrypt works. The only difference I can see is that the Java example uses a StringBuffer where I use a StringBuilder.
Thank you, Artjom B!
byte[] out1 = Convert.FromBase64String(name);
Should have been
byte[] out1 = Hex.Decode(name);
From there, all I had to do was convert the Hex to a string.

Replicate C# encryption/decryption in PHP

I have been given a set of codes from a third party that need encrypting/decrypting however the sample encryption code they gave me was in C# and I am primarily a front-end PHP developer.
I have set-up a slimmed down working example of the code I was provided
here using the sample key of A818163DD5E0DE87.
public static byte[] HexStringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2) {
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
// Convers a byte array to a HEX string
public static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder hexString = new StringBuilder(bytes.Length * 2);
for (int i = 0; i < bytes.Length; i++)
{
hexString.Append(bytes[i].ToString("X2"));
}
return hexString.ToString();
}
public static byte[] Encrypt()
{
string plainText = "GROW06BP";
DESCryptoServiceProvider desCrypto = new DESCryptoServiceProvider();
desCrypto.Key = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.IV = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.Mode = CipherMode.CBC;
desCrypto.Padding = PaddingMode.Zeros;
// Create a buffer for the Plain Text using ASCIIEncoding
byte[] plaintextBytes = (new ASCIIEncoding()).GetBytes(plainText);
// Create a memory stream for the encrypted bytes
MemoryStream msEncrypt = new MemoryStream();
// Create a CryptoStream using the memory stream and the passed Algorithm
CryptoStream csEncrypt = new CryptoStream(msEncrypt, desCrypto.CreateEncryptor(), CryptoStreamMode.Write);
// Write the plaintext to the CryptoStream
csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
// Close the CryptoStream
csEncrypt.Close();
// Read the Encrypted bytes into our buffer
byte[] encryptedTextBytes = msEncrypt.ToArray();
// Close the Memory Stream
msEncrypt.Close();
// And return the encrypted buffer
return encryptedTextBytes;
}
I have scoured stack overflow and other sites in an attempt to replicate this in PHP but nothing comes close to the correct output. I'm also confused by which cipher I am meant to be using and how to convert the key and iv to match the C# example. Below is what I have attempted so far.
$key = unpack('H*', "A818163DD5E0DE87");
$key = "A818163DD5E0DE87";
$iv = $key;
$plaintext = "GROW06BP";
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);
Any help would be appreciated.
Things you need to consider:
DESCryptoServiceProvider -> mcrypt_module_open('des'
desCrypto.Mode = CipherMode.CBC; -> mcrypt_module_open(...,..., 'cbc',
key,iv and the cipher output are "treated" with HexStringToByteArray(), pack('H*) can undo that
So, given the output of the .net fiddle (7860D97E56DA6A40) that leads to
<?php
$msgHex = '7860D97E56DA6A40';
$keyHex = 'A818163DD5E0DE87';
$ivHex = 'A818163DD5E0DE87'; // really? invalidates the use-case of an iv :-/
// this reverts the effect of HexStringToByteArray()
$msg = pack('H*', $msgHex);
$key = pack('H*', $keyHex);
$iv = pack('H*', $ivHex);
// add error handing !
$module = mcrypt_module_open('des', '', 'cbc', '');
mcrypt_generic_init($module, $key, $iv);
$plaintext = mdecrypt_generic($module, $msg);
mcrypt_generic_deinit($module);
echo $plaintext;
output: GROW06BP
As I've already mentioned in my comment, you're using the wrong algorithm in your PHP code since it's Rijndael. What you should use is MCRYPT_DES.
$key = "A818163DD5E0DE87";
// Here you need pack instead of unpack
$packKey = pack("H*",$key);
// you should use the key as the initialization vector
// use something like mcrypt_create_iv to generate an IV
$iv = $packKey;
$plaintext = "GROW06BP";
// replaced MCRYPT_RIJNDAEL_128 with MCRYPT_DES
$ciphertext = mcrypt_encrypt(MCRYPT_DES, $packKey, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);
This will produce the same output as the C# code

Encrypt / Decrypt data with AES between c# and PHP - decrypted data starts with 255,254

I have to request data from an external existing webservice written in C#.
This webservice requires some of the data to be encrypted (The connection uses an SSL connection, some of the data is aes encrypted)
On the php site openssl is used for decrypting.
The following settings are used on the c# site
(This are the default values for the AesCryptoServiceProvider):
Algorithm: AES
Padding: PKCS7
Mode: CBC
Keysize: 256
The padding for PKCS7 works as following:
01 If 1 byte is missing
02 02 If 2 bytes are missing
and so on
so this values are not added by the padding.
What am I doing wrong?
I've checked this with c#, php and ruby - the decrypted data starts with 255, 254
To reproduce use the following parameters:
data:1234567890123456
key: First1
salt(iv):Data
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
namespace crypto_test
{
class MainClass
{
public static void Main(string[] args)
{
bool running = true;
while (running)
{
Console.WriteLine("Enter data:");
var data = Console.ReadLine();
Console.WriteLine("Enter key:");
var key = Console.ReadLine();
Console.WriteLine("Enter iv:");
var iv = Console.ReadLine();
Console.WriteLine("Enter d for decode");
var decode = (Console.ReadLine() == "d");
string encoded=Crypt(data, key, iv, decode);
Console.WriteLine(encoded);
if (!decode)
{
encoded= Crypt(encoded, key, iv, true);
Console.WriteLine(encoded);
}
Console.WriteLine("quit to exit");
running = !(Console.ReadLine() == "quit");
}
}
public static string Crypt(string value, string password, string salt, bool decrypt)
{
DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));
SymmetricAlgorithm algorithm = new AesCryptoServiceProvider();
byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);
Console.WriteLine("rbKey: size:{0} key:{1}", (algorithm.KeySize >> 3), GetHex(rgbKey));
Console.WriteLine("rgbIV: size:{0} key:{1}", (algorithm.BlockSize >> 3), GetHex(rgbIV));
ICryptoTransform transform = decrypt ? algorithm.CreateDecryptor(rgbKey, rgbIV) : algorithm.CreateEncryptor(rgbKey, rgbIV);
Console.WriteLine("Mode {0}", algorithm.Mode);
Console.WriteLine("PAdding {0}", algorithm.Padding);
using (MemoryStream buffer = new MemoryStream())
{
using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
{
try
{
if (decrypt)
{
byte[] data = Convert.FromBase64String(value);
stream.Write(data,0,data.Length);
}
else
{
using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
{
writer.Write(value);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
byte[] buff = buffer.ToArray();
if (decrypt)
{
return Encoding.Unicode.GetString(buff) + "\r\n" + GetHex(buff);
}
else
return Convert.ToBase64String(buff);
}
}
public static string GetHex(byte[] data)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; ++i)
sb.Append(data[i].ToString("X2"));
return sb.ToString();
}
}
}
I have not found an equivalent to Rfc2898DeriveBytes until now,
so I copied the key and iv
php
<?php
$salt='Data';
$pass='First1';
$data='1234567890123456';
$encrypted_base64='VKNd9Pi+cttaM6ne8pzAuFbH1U0gJiJ2Wlbbr1rU5z8vbIfAS6nb0/5py4p54aK7';
$encrypted=base64_decode($encrypted_base64);
$key = pack('H*', "30EE7F95F0EF4835F048A481424F2F52EE21B7CEB97F8CC437E5949DB53797D9");
$iv = pack('H*', "B29F5ECF7057065758102385509F0637");
$cipher='AES-256-CBC';
$decrypted = openssl_decrypt($encrypted,$cipher, $key,true,$iv);
for($i =0; $i<strlen($decrypted);++$i)
{
echo "char:" . ord($decrypted[$i])."<br/>";
}
echo $decrypted
?>
ruby:
require ('openssl')
require ('base64')
while true
enc_data='VKNd9Pi+cttaM6ne8pzAuFbH1U0gJiJ2Wlbbr1rU5z8vbIfAS6nb0/5py4p54aK7'
data = Base64.decode64(enc_data)
key_hex='30EE7F95F0EF4835F048A481424F2F52EE21B7CEB97F8CC437E5949DB53797D9'
iv_hex='B29F5ECF7057065758102385509F0637'
key = [key_hex].pack('H*')
iv = [iv_hex].pack('H*')
decipher = OpenSSL::Cipher::AES.new(256, :CBC)
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.update(data) + decipher.final
puts plain
puts plain.bytes
end
Good news, your decryption seems to work OK.
What you are seeing in the decrypted ciphertext is the byte order mark for UTF-16 LE, which is (incorrectly) indicated by Microsoft as Encoding.Unicode. You need to do either one off two things:
decode the text with a decoder that groks UTF-16 LE including byte order mark;
encode using much more reasonable UTF-8 encoding (in the C# code).
Personally I would put a strong preference on (2).

SSCrypto from Objective C to C#

I am trying to encrypt below base64 string in objective c .. Now i need to decrypt the output of below code in C# ... Please advice simplest way as i don't want to install any libs at server.
Please advice how can convert encripted string back to base64 using C# .
Thanks
My Objective c Code for encripting the base 64
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
SSCrypto *crypto;
NSString *password =#"abcdefghijklmnoqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnoqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz";
NSData *seedData1 = [password dataUsingEncoding:NSUTF8StringEncoding];
crypto = [[SSCrypto alloc] initWithSymmetricKey:seedData1];
NSString *base64String = #"SUkqAAgAAAARAP4ABAABAAAAAAAAAAABAwABAAAAsAQAAAEBAwABAAAAEAIAAAIBAwABAAAAAQAAAAMBAwABAAAABAAAAAYBAwABAAAAAAAAAAoBAwABAAAAAQAAABEBBAABAAAACgEAABIBAwABAAAAAQAAABUBAwABAAAAAQAAABYBAwABAAAAEAIAABcBBAABAAAA3yUAABoBBQABAAAA2gAAABsBBQABAAAA4gAAACUBBAABAAAAAAAAACgBAwABAAAAAgAAADEBAgAgAAAA6gAAAAAAAADIAAAAAQAAAMgAAAABAAAAQ29tcHJlc3NlZCB3aXRoIFBBTklOSSBJbWFnZSsAAAAmoy1xRBcev/r/LSUkbRxE+cRxGpEdF0Rw2EcNhHDIBcufR2+R0XZJjI6OIj5HjCPRHR9F0R8wCmRwXI6I+eROjiNxpEdkdEdl2R8ujTMMuy+R0R8j5HZvNo2yOzcXyOiPkdFzLsjxHGRwbC5lwJQaQRDaCchYbAxEREREREREREREREREREREREREREREREREI0BuRww+RIyPFw2MSnIccp0yY58fgxZ5EcKaVhJdx//pL0OQwm5EA///WlgnWSAb/+q9KEgt4X+961qgtKkZJCMH/XlnojiSvNBUkmSCPZBiQlT//iR7pdK0tgnwzep3zv//DLtrqmuLDodf/X7w2lasnCq7CWPf/0l2a6sIIRSVjoLFf9/3sMJ+jrkIjeTonRHRtE6N5A86ohEQtF0d6Ijol0IiIiIiIiIiIi0IiIiIiOIiIiIiIiIiIiIiIiIiIiIgwjtb8tBIhXABABA==";
[crypto setClearTextWithString:base64String];
NSData *cipherText = [crypto encrypt:#"aes256"];
NSLog(#"Cipher text: '%#' using %#", [cipherText encodeBase64WithNewlines:NO], #"aes256");
NSLog(#" ");
[ pool release];
Below is my C# code for Decryption
public static string DecryptString(string base64StringToDecrypt, string passphrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passphrase)))
{
byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt);
ICryptoTransform ictD = acsp.CreateDecryptor();
// TripleDES.
//RawBytes now contains original byte array, still in Encrypted state
//Decrypt into stream
MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length);
CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read);
//csD now contains original byte array, fully decrypted
//return the content of msD as a regular string
return (new StreamReader(csD)).ReadToEnd();
}
private static AesCryptoServiceProvider GetProvider(byte[] key)
{
AesCryptoServiceProvider result = new AesCryptoServiceProvider();
result.BlockSize = 128;
result.KeySize = 128;
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7;
result.GenerateIV();
result.IV = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte[] RealKey = GetKey(key, result);
result.Key = RealKey;
// result.IV = RealKey;
return result;
}
private static byte[] GetKey(byte[] suggestedKey, SymmetricAlgorithm p)
{
byte[] kRaw = suggestedKey;
List<byte> kList = new List<byte>();
for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8)
{
kList.Add(kRaw[(i / 8) % kRaw.Length]);
}
byte[] k = kList.ToArray();
return k;
}
Please advice if anything is missing or if i have done something gross wrong ..
I have lost more than 2 days in searching.
You can do this easily with the AesManaged class. See:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx

Categories