Converting RSA encryption code from C# to php - c#

I have c# code for encryption. And I need to convert it with same logic in PHP.
// Public key to be used for encryption
String publicKey="yxnxuhj2322i23k232sasas123121";
// Sample data to be encrypted
String data="test";
//Encryption logic
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(publicKey));
byte[] plainBytes = Encoding.UTF8.GetBytes(data);
byte[] encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
string encryptedString = Convert.ToBase64String(encryptedBytes);
PHP Code:
include('Crypt/RSA.php');
$a = 'yxnxuhj2322i23k232sasas123121';
$a = base64_decode($a);
$rsa= parseCSBBlob($a);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
define('CRYPT_RSA_PKCS15_COMPAT', true);
$user=utf8_encode("test");
$enc_user= $rsa->encrypt($user);
$enc_user=base64_encode($enc_user);
function parseCSBBlob($str) {
// from https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
extract(unpack('atype/aversion/vreserved/Valgo', $str));
if (ord($type) != 6) { // 6 == PUBLICKEYBLOB
return false;
}
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
if ($algo != 0x0000a400) { // 0x0000a400 == CALG_RSA_KEYX
return false;
}
$str = substr($str, 8); // aavV
extract(unpack('Vmagic/Vbitlen/Vpubexp', $str));
if ($magic != 0x31415352) { // RSA1
return false;
}
$str = substr($str, 12); // VVV
if (strlen($str) != $bitlen / 8) {
return false;
}
$str = strrev($str);
$rsa = new Crypt_RSA();
$rsa->loadKey(array(
'e' => new Math_BigInteger($pubexp, 256),
'n' => new Math_BigInteger($str, 256)
));
return $rsa;
}
I have used the parseCSBBlob method from other stackoverflow post. But it wont work. I am getting encryption from this code but it is not get decrypted in C#. I could not get the ImportCspBlob method in PHP. Encryption should be done in PHP and decryption is done in C#.

Related

Decrypt and verify hash for SHA256 - c#

I am trying to decrypt and validate the hash but at times of decrypting, it throws me the error 'Key does not exist' and at the time of validating the hash return False
https://payvyne.readme.io/docs/webhooks
Signature:
HEjoCsghC9X0slrE2DprptDLYdoA7jaw4Jl7vpJVxzx9GNJEiO3pYGLDPhLmVqk98QJJ/FuiS5J+fvp+msr3Y8aFzKqjRQXj5TBELT38N+A7I8y3Vc0mgeR0aDMx7I83yhfkcoyhdiGJibzqQ5SYFZ0nnEVHYXheLUlga45yg/McDICtMm6lhnrPWEuHzoZTQkhsrLN/1W1PtLjJ2DickWB78PmhpeflL2Cpe6qS3qCclqFGZ7HIl9OoxU4WXpTYgxw7eixAKB7apFdFqea4BnGravfENNl97pOBuU6fRof4KtMczVagQw3QnxFD3BBtpTepRaT+jHY8wStXUG1bxllH32WiA9CVcpY4mxKhpxzQ8YD0b+3OgkpzZYS+BVVAdVazMJeEAw7v/zaxpjbR+Zo5l9vOLdyatwM75qpwMoKnMeKJHeRytEOK54al49OHiaE+v1OkOhJA0zh5nLzEIZanIdf+hXHDz3Euecs/p0cABiFNmhzYY5fl8qEytK6j2CjXQOYgljG5dqPm7M9CW36ntZTDaIEVWql3jdi9frxc4/82w1jhROFL0pBG1zz8nimAEesB1AaxmNqW7BIxULweX7eaReeo/dIqDSbmFuT+TikPQo4XRtmpDqO37Y9P6q7ZXtHOFopSaykHUHs+NgrKlBJMM5ADg5bHWm2Qows=
Public key:
pA6ULfXWrIMq-qvxn_0CykoStq0ZMYm63lHsuXTsE4q4tgekLJDW2Lnf35ilbFU_vybBdyeJAphpsYc4P0eJBt_z2T62HAV3gnwp_GU6hWIo8faK31TSXIrLmGjZlAVynAxjFYZoNxMeZuwEXpxG4bRGs58P7XSx1fAzedX6oGIlcSLljKH4I1BHt6gJhPIHYNXQzq_a0hX54C1m1VDVP_kot8ui1YKZil_riROK_Xk4ktnOTAqXo9z4uNBqzzH2k0J2YNiCb8VOdbp7kjmH9sPLI-jb-ociy0wSkGZc1e8saGIkkSm4eUASvX_M_TTDD99OrgoIS2Vx07Tw4lK5yd28EMVBUzy2OypuPVf9PyoDGv_4241x5PpJsA9IKocD7AgwxJ3E7FBFhvuSP8c5wspkbQxBwv5nnk2zAxuZsiJeK0o3JSxjkZJEkeVY4mA3VV9SvSXEKAFg2h9J3CR9PTwrZoVBruycVtWJ4it5jroXff-aGlLoRAO0g3gtfjkJb3tw6SJTFOA49iJci76Mj8Adz3eeEEGxTxfDzh_lq0jXxTk7cQSaR2_ChYLHaoorrrFmAvWgDH_lSvlISIgey-SzUoJM9RAy4gVFdmg-XCQQlpMh_d1-IACO3EfBvYKWE-6uGIqx1nZhn9WIDdSqMp6940xRxl0vQy8vYCQ5q8U
Data for Sign in string:
{"type":"PAYMENT_STATUS_CHANGE","paymentId":"1c6e834f074ec941","status":"FAILED","timestamp":1652688286662,"amount":"164.69","currency":"GBP","description":"This is test payment","paymentType":"ONE_OFF","bankName":"Diamond bank","destinationAccount":"GBP2","createdAt":"2022-05-16T08:04:32.994","updatedAt":"2022-05-16T08:04:46.662","customerReference":"1199","refundedAmount":"0.00"}
Expo (exponent):
AQAB
Below is the code to Decrypt the signature using public key.
public static void DecryptUsingPublicKey(string publicKey, string expo, string signature)
{
var modulus = ConvertToBase64(publicKey);
var exponent = Convert.FromBase64String(expo);
RSACryptoServiceProvider csp = new RSACryptoServiceProvider(2048);
var _publicKey = csp.ExportParameters(false);
_publicKey.Modulus = modulus;
_publicKey.Exponent = exponent;
csp.ImportParameters(_publicKey);
var dataBytes = ConvertToBase64(signature);
var plainText = csp.Decrypt(dataBytes, false);
var returnData = Encoding.Unicode.GetString(plainText);
Console.WriteLine($"value: {returnData}");
}
Below is the code for Verify signature using public key
public static void VerifySignature(string signature, string pKey, string dataForSign)
{
string pKeyNew = pKey;
pKeyNew = pKeyNew.Replace("_", "/").Replace("-", "+");
string publicKey = $"<RSAKeyValue><Modulus>{pKeyNew}==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
var encoder = new UTF8Encoding();
byte[] dataForSignAsBytes = encoder.GetBytes(dataForSign);
byte[] signatureAsBytes = ConvertToBase64(signature);
RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(publicKey);
var hashData = SHA256.Create().ComputeHash(dataForSignAsBytes);
var result1 = rsaCryptoServiceProvider.VerifyData(dataForSignAsBytes, CryptoConfig.MapNameToOID("SHA256"), signatureAsBytes);
var result2 = rsaCryptoServiceProvider.VerifyHash(hashData, CryptoConfig.MapNameToOID("SHA256"), signatureAsBytes);
var result3 = rsaCryptoServiceProvider.VerifyHash(hashData, signatureAsBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var result4 = rsaCryptoServiceProvider.VerifyData(dataForSignAsBytes, signatureAsBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Console.WriteLine(result1);
Console.WriteLine(result2);
Console.WriteLine(result3);
Console.WriteLine(result4);
}
ConvertToBase64 function
public static byte[] ConvertToBase64(string data)
{
byte[] cyperBuffer;
string dataNew = data;
dataNew = dataNew.Replace("_", "/").Replace("-", "+");
try
{
if (dataNew.Substring(dataNew.Length - 1) != "=")
{
dataNew += "=";
}
cyperBuffer = Convert.FromBase64String(dataNew);
}
catch
{
dataNew += "=";
try
{
cyperBuffer = Convert.FromBase64String(dataNew);
}
catch
{
//If any error occured while convert to base64 then append '=' at the end.
dataNew += "=";
cyperBuffer = Convert.FromBase64String(dataNew);
}
}
return cyperBuffer;
}
This is a conversion mistake; you need to decode the base 64 signature, not encode the signature, so the following line is wrong:
byte[] signatureAsBytes = ConvertToBase64(signature);
it should be something like:
byte[] signatureAsBytes = ConvertFromBase64(signature);
Decryption is modular exponentiation with a private key. Furthermore, encryption normally uses a different padding scheme than signature generation, so you'd expect that the unpadding would fail if you try and decrypt. Only verification is possible.

Getting bad padding exception while decrypting using AES CBC PCKS7 padding

So I have some code in Java for encrypting and decrypting objects and I've been trying to do the same in C# so my server and client can decrypt and encrypt messages. At the moment the last piece of the puzzle I need to fix is my C# decryption. When attempting to decrypt, I usually get a bad padding exception of sorts. However, Java is using PCKS5 padding and C# is using PCKS7 padding which if I understand correctly are virtually indistinguishable.
#RequiredArgsConstructor
#Getter
public class EncryptedBytes {
private final byte[] data;
private final byte[] params;
private final String paramAlgorithm;
}
/**
* Encrypt object with password
*
* #param data Object to be encrypted
* #param secret Password to use for encryption
* #return Encrypted version of object
*/
public static EncryptedBytes encrypt(String data, SecretKey secret) throws InvalidKeyException {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
// properly encode the complete ciphertext
//logEncrypt(password, object);
byte[] encodedData = cipher.doFinal(data.getBytes(CharsetUtil.UTF_8));
byte[] params = cipher.getParameters().getEncoded();
String paramAlgorithm = cipher.getParameters().getAlgorithm();
return new EncryptedBytes(encodedData, params, paramAlgorithm);
} catch (InvalidKeyException e) {
throw e;
} catch (NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException | BadPaddingException | IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Decrypt data with secret
*
* #param encryptedBytes Object to be decrypted
* #param secret Password to use for decryption
* #return Decrypted version of object
*/
public static String decrypt(EncryptedBytes encryptedBytes, #NonNull SecretKey secret) throws InvalidKeyException {
try {
// get parameter object for password-based encryption
AlgorithmParameters algParams = AlgorithmParameters.getInstance(encryptedBytes.getParamAlgorithm()); // getParamAlgorithm usually just returns "AES"
if (algParams == null) throw new IllegalArgumentException("EncryptedBytes.Parameters are not valid");
// initialize with parameter encoding from above
algParams.init(encryptedBytes.getParams());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, algParams);
return new String(cipher.doFinal(encryptedBytes.getData()), CharsetUtil.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | IOException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
Now in C# I have a very close implementation to the Java code above.
public class EncryptedBytes
{
[NotNull]
public List<sbyte> data { get; }
[NotNull]
[JsonProperty("params", Required = Required.Always)]
[JsonPropertyName("params")]
public List<sbyte> keyParams { get; }
[NotNull]
public string paramAlgorithm { get; }
public EncryptedBytes(IEnumerable<sbyte> data, [JsonProperty(propertyName: "params")] IEnumerable<sbyte> keyParams, string paramAlgorithm)
{
this.data = data.ToList();
this.keyParams = keyParams.ToList();
this.paramAlgorithm = paramAlgorithm;
}
}
public static EncryptedBytes encrypt(AesCryptoServiceProvider aesCryptoServiceProvider, string plainText,
Encoding encoding)
{
if (encoding == null) encoding = StaticHandler.encoding; // UTF_8
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (aesCryptoServiceProvider.Key == null || aesCryptoServiceProvider.Key.Length <= 0)
throw new ArgumentNullException("Key");
if (aesCryptoServiceProvider.IV == null || aesCryptoServiceProvider.IV.Length <= 0)
throw new ArgumentNullException("IV");
ICryptoTransform transform = aesCryptoServiceProvider.CreateEncryptor();
var encodedText = encoding.GetBytes(plainText);
var encryptedText =
transform.TransformFinalBlock(encodedText, 0, encodedText.Length).Select(Convert.ToSByte);
var derOctetString = new DerOctetString(aesCryptoServiceProvider.IV);
return new EncryptedBytes(encryptedText, derOctetString.GetEncoded().Select(Convert.ToSByte), "AES");
}
public static string decrypt([NotNull] EncryptedBytes encryptedBytes, AesCryptoServiceProvider aesCryptoServiceProvider, Encoding? encoding)
{
if (encoding == null) encoding = StaticHandler.encoding;
var cipherText = encryptedBytes.data.Select(arg => (byte) arg).ToArray();
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (aesCryptoServiceProvider.Key == null || aesCryptoServiceProvider.Key.Length <= 0)
throw new ArgumentNullException("Key");
if (aesCryptoServiceProvider.IV == null || aesCryptoServiceProvider.IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
var transform = aesCryptoServiceProvider.CreateDecryptor();
string plaintext;
var keyParams = encryptedBytes.keyParams.Select(b => (byte) b).ToArray();
var octetString = (DerOctetString) Asn1Object.FromByteArray(keyParams);
aesCryptoServiceProvider.IV = octetString.GetOctets();
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
plaintext = encoding.GetString(transform.TransformFinalBlock(cipherText, 0, cipherText.Length));
return plaintext;
}
The main code in question is this:
var transform = aesCryptoServiceProvider.CreateDecryptor();
string plaintext;
var keyParams = encryptedBytes.keyParams.Select(b => (byte) b).ToArray();
var octetString = (DerOctetString) Asn1Object.FromByteArray(keyParams);
aesCryptoServiceProvider.IV = octetString.GetOctets();
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
plaintext = encoding.GetString(transform.TransformFinalBlock(cipherText, 0, cipherText.Length));
For testing purposes, you may use this value as an example of data that is parsed (EncryptedBytes class converted to JSON)
{"data":[-91,-105,-48,-75,18,-64,-12,-122,56,76,17,101,54,65,53,-10],"params":[4,16,81,-32,-95,-80,-81,100,-81,58,49,-36,35,21,-115,-110,111,-2],"paramAlgorithm":"AES"}
This should just return empty brackets as plaintext.
Expected result:
{}
You may use this key: (both values are the same key, written differently)
Byte array: 15,215,133,73,75,92,34,113,122,135,36,209,240,159,54,165,30,23,86,73,166,7,166,192,209,145,68,167,19,205,105,55
Base64: D9eFSUtcInF6hyTR8J82pR4XVkmmB6bA0ZFEpxPNaTc=

How to triple des C# method according to swift method

How to change C# encryption method to the same as swift? I tried below code, but it's converting the string different. I want according to same as swift due to decryption method. I am using 3des. My C# method encrypt/decrypt is working fine.
I want same as C# in Swift.
C#
public static string Encrypt(string PlainText)
{
try
{
if (PlainText.Length > 0)
{
string key = "FIFEDCBA98765432104AABFD";
byte[] PlainTextArray = UTF8Encoding.UTF8.GetBytes(PlainText);
byte[] keyArray = MD5.CreateMd5ByteArray(key);
TripleDESCryptoServiceProvider TripleDes = new TripleDESCryptoServiceProvider();
TripleDes.Key = keyArray;
TripleDes.Mode = CipherMode.ECB;
TripleDes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDes.CreateEncryptor();
byte[] CipherString = cTransform.TransformFinalBlock(PlainTextArray, 0, PlainTextArray.Length);
TripleDes.Clear();
return Convert.ToBase64String(CipherString, 0, CipherString.Length);
}
else
{
return null;
}
}
catch (Exception ex)
{
throw;
}
}
SWIFT
func tripleDesEncrypt(PlainString: String) -> String{
let keyData = "FIFEDCBA98765432104AABFD"
let PlainStringvar = PlainString
guard let data = PlainStringvar.data(using: .utf8) else {
return ""
}
let cryptData = NSMutableData(length: Int(data.count) + kCCBlockSize3DES)!
let keyLength = size_t(kCCKeySize3DES)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes, keyLength,
nil,
data.bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
var base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
return base64cryptString//// encodeString(str: base64cryptString)
} else {
print("Error: \(cryptStatus)")
}
return ""
}
Your problem in C# appears to be this line:
byte[] keyArray = MD5.CreateMd5ByteArray(key);
Assuming that function (which is not part of the .NET BCL, so I assume it's something custom that you wrote) creates an MD5 hash of your 3DES key, that's the only difference between your C# and Swift versions.
In Swift, you encrypt the value using a key which is the UTF-8 encoded value of "FIFE...".
In C#, you encrypt the value using a key which is the MD5 hash of the UTF-8 encoded value if "FIFE...".
If you replace that line with the following one:
var keyArray = Encoding.UTF8.GetBytes(key);
then both functions return the same ciphertext for the same plaintext values.

Sign with PHP, verify with C#

A have PHP code to sign the message (using phpseclib 2.0):
function sign($plaintext, $key, $password) {
$rsa = new RSA();
$rsa->setPassword($password);
$rsa->loadKey(file_get_contents($key));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$signature = $rsa->sign(hash('sha256', $plaintext));
return base64_encode($signature);
}
Public and private keys format is PEM. I need to verify this signature with C#. I am trying this code, but it returns false:
public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey)
{
bool success = false;
using (var rsa = new RSACryptoServiceProvider())
{
var encoder = new UTF8Encoding();
byte[] bytesToVerify = encoder.GetBytes(originalMessage);
byte[] signedBytes = Convert.FromBase64String(signedMessage);
try
{
rsa.ImportParameters(publicKey);
SHA256Managed Hash = new SHA256Managed();
byte[] hashedData = Hash.ComputeHash(bytesToVerify);
success = rsa.VerifyData(hashedData, CryptoConfig.MapNameToOID("SHA256"), signedBytes);
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
return success;
}
Usage:
RSACryptoServiceProvider rsa = PemKeyUtils.PemKeyUtils.GetRSAProviderFromPemFile("public.key");
MessageBox.Show(VerifyData("my message", #"ZpQMPYlMIgME/H0sRYBnyEf/yJ/eBc5bznYZ2nMFn/I6Ts3u8P3x0QgzbUxPnhUgfKhcrEC2UgffyzWzCfwT3Bs+lm6Q89N5bkWK08WKnWaFxr2GQ6+gNyPyUKUgfy851xIHU7EMR6bZt/IndPC+lAAXSxxddPwLelrI8ktgyMVvMUzfCh3AeNCBuY5sSRwkAKH2myPBThJKNjKSZVEb4tO4oiPPWlBuifqmWvbQeMFuKANY0dZNCUFVjlnkaHnwVNzVs1BhNTEML2MKmWvKofafbtcG8J1F+7PapppZwT7OFqhosCSrrzRX49cR4y/7b0syJozmJSebKDpy6FPefA==", rsa.ExportParameters(false)).ToString());
PemKeyUtils class from this answer.
What's wrong? How can I verify signature with C#?
VerifyData() computes the hash itself, so you've ended up hashing the data twice in your C# code. Just provide the data directly to VerifyData() without hashing it yourself.
EDIT: Ok, now I see that you are also hashing it twice on the php side, the first time with SHA1 and the second time with SHA256. Just hash it once, using SHA256, just it like shows in the examples.
function sign($plaintext, $key, $password) {
$rsa = new RSA();
$rsa->setPassword($password);
$rsa->loadKey(file_get_contents($key));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$rsa->setHash('sha256')
$signature = $rsa->sign($plaintext);
return base64_encode($signature);
}

Converting AES encryption token code in C# to php

I have the following .Net code which takes two inputs. 1) A 128 bit base 64 encoded key and 2) the userid. It outputs the AES encrypted token.
I need the php equivalent of the same code, but dont know which corresponding php classes are to be used for RNGCryptoServiceProvider,RijndaelManaged,ICryptoTransform,MemoryStream and CryptoStream.
Im stuck so any help regarding this would be really appreciated.
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
class AESToken
{
[STAThread]
static int Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: AESToken key userId\n");
Console.WriteLine("key Specifies 128-bit AES key base64 encoded supplied by MediaNet to the partner");
Console.WriteLine("userId specifies the unique id");
return -1;
}
string key = args[0];
string userId = args[1];
StringBuilder sb = new StringBuilder();
// This example code uses the magic string “CAMB2B”. The implementer
// must use the appropriate magic string for the web services API.
sb.Append("CAMB2B");
sb.Append(args[1]); // userId
sb.Append('|'); // pipe char
sb.Append(System.DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ssUTC")); //timestamp
Byte[] payload = Encoding.ASCII.GetBytes(sb.ToString());
byte[] salt = new Byte[16]; // 16 bytes of random salt
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(salt); // the plaintext is 16 bytes of salt followed by the payload.
byte[] plaintext = new byte[salt.Length + payload.Length];
salt.CopyTo(plaintext, 0);
payload.CopyTo(plaintext, salt.Length);
// the AES cryptor: 128-bit key, 128-bit block size, CBC mode
RijndaelManaged cryptor = new RijndaelManaged();
cryptor.KeySize = 128;
cryptor.BlockSize = 128;
cryptor.Mode = CipherMode.CBC;
cryptor.GenerateIV();
cryptor.Key = Convert.FromBase64String(args[0]); // the key
byte[] iv = cryptor.IV; // the IV.
// do the encryption
ICryptoTransform encryptor = cryptor.CreateEncryptor(cryptor.Key, iv);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
cs.Write(plaintext, 0, plaintext.Length);
cs.FlushFinalBlock();
byte[] ciphertext = ms.ToArray();
ms.Close();
cs.Close();
// build the token
byte[] tokenBytes = new byte[iv.Length + ciphertext.Length];
iv.CopyTo(tokenBytes, 0);
ciphertext.CopyTo(tokenBytes, iv.Length);
string token = Convert.ToBase64String(tokenBytes);
Console.WriteLine(token);
return 0;
}
}
Please help.
Thank You.
We are also trying figure out the same C# in PHP. You can post your code without the key.
First approach:
// Open the cipher:
// Using Rijndael 128 in CBC mode.
$m = mcrypt_module_open('rijndael-128', '', 'cbc', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($m), MCRYPT_RAND);
// Initialize the encryption:
mcrypt_generic_init($m, (base64_decode($key_)), $iv);
// Encrypt the data:
$cryptext = mcrypt_generic($m, $plain_text);
//echo "IV SIZE ".mcrypt_enc_get_iv_size($m);
$tx2 = base64_encode($iv.$cipherText);
// Close the encryption handler:
mcrypt_generic_deinit($m);
// Close the cipher:
mcrypt_module_close($m);
Second approach for initialization:
$m = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$iv_size = mcrypt_enc_get_iv_size($m);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($m), MCRYPT_RAND);
$key128 = base64_decode($key_);
// Encrypt the data:
$cryptext = mcrypt_generic($m, $plain_text);
$tx2 = base64_encode($iv.$cipherText);
// Close the encryption handler:
mcrypt_generic_deinit($m);
You would use the mcrypt library in PHP to implement the same functionality.
You can see the following code that works:
<?php
class UserData
{
public $email;
public $name;
public $expires;
}
class Application
{
private $api_key = "<private_key>";
private $app_key = "appkey";
public function run()
{
$user = new UserData();
$date = new DateTime(null, new DateTimeZone('UTC'));
$date->modify('+5 minute');
$user->expires = $date->format('c');
$user->email = "testing#domain.com";
$user->name = "PHP5 Example";
$encrypted_data = $this->encryptUserData($user);
// Example login URL
printf("http://<domain>/multipass?sso=%s", $encrypted_data);
}
private function encryptUserData($user_data)
{
$app_key = $this->app_key;
$api_key = $this->api_key;
$json = json_encode($user_data);
$salted = $api_key . $app_key;
$saltedHash = substr(sha1($salted, true), 0, 16);
$pad = 16 - (strlen($json) % 16);
$data = $json . (str_repeat(chr($pad), $pad));
if (!function_exists('mcrypt_encrypt'))
throw new Exception('Mcrypt extension is not installed for PHP.');
$aes = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $saltedHash, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
$b64token = base64_encode($aes);
$b64token = rtrim(str_replace(array('+', '/'), array('-', '_'), $b64token), '=');
return $b64token;
}
}
$app = new Application();
$app->run();
?>
I hope it will be helpful for you. Thanks.

Categories

Resources