Convertir encriptación en PHP 3DES en C#

Recientemente ha avisado que el sistema de pago por TPV virtual de Redsys se va a actualizar. En esta actualización se van a incorporar medidas de cifrado más potentes que la firma actual que se tiene implementado. Para ello los bancos han enviado cierta documentación (un poco tarde…) para hacer esta migración, puesto que el 23/11/2015 se supone que dejará de funcionar el sistema de encriptación actual.

Realizando la migración en mi empresa me he encontrado con un escollo que me ha costado un poco de solventar, y por lo que veo a muchos más desarrolladores de .NET les ha sucedido lo mismo. El problema está en el cifrado triple DES.

Este es el código de ejemplo que te facilitan en Redsys para realizar este cifrado.

function encrypt_3DES($message, $key){
// Se establece un IV por defecto
$bytes = array(0,0,0,0,0,0,0,0); //byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
$iv = implode(array_map("chr", $bytes)); //PHP 4 = 4.0.2


// Se cifra
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv); //PHP 4 >= 4.0.2
return $ciphertext;
}


$key = $this->decodeBase64($key);
$ciphertext = $this->encrypt_3DES($message, $key);

La variable $message sería el texto a encryptar (en el caso de Redsys el número de pedido). La variable $key es la clave de encriptación de Redsys que previamente la decodificamos en Base64.
Al final obtenemos un resultado ($ciphertext) que es un array de bytes.

Ahora viene cuando hacemos lo mismo en .NET C#.


///
/// Uso de la encriptación TripleDES con IV todo 0 -> byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
/// Esta encriptación se usa así para los TPV's de Redsys
///


///Texto a encriptar ///Clave de la encriptación en un array de Bytes ///
public static byte[] EncriptarTripleDES_IV_0(string texto, byte[] key)
{
using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
{
byte[] iv_0 = { 0, 0, 0, 0, 0, 0, 0, 0 };  //same IV that Redsys
byte[] toEncryptArray = Encoding.ASCII.GetBytes(texto);
tdes.IV = iv_0;
//assign the secret key
tdes.Key = key;
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0,toEncryptArray.Length);
//Clear to Best Practices
tdes.Clear();
return resultArray;
}
}

Esta función nos devuelve el mismo resultado que la orginial proporcionada por Redsys en PHP.

Como hacer comentarios en ASP.NET C#

Asp  .NEt logtoipo

Si necesitas comentar algún código mientras estás utilizando ASP.NET en el código HTML, puedes hacerlo con la siguiente sintáxis:

<%– Código a comentar –%> 

Todo lo que pongas entre los símbolos <%– y –%> será obviado por el servidor, incluso si es multilínea.

Una cosa muy cómoda en Visual Studio, es seleccionar o ponerte en la línea que quieres comentar y luego utilizar esta combinación de teclas Cntrl + e y seguidamente Cntrl + c, de esta manera tu código se comentará completamente sólo.

También existe la forma de descomentar automáticamente y sería con esta combinación des teclas Cntrl + e y seguidamente Cntrl + u.

Ejemplo:

</html>
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>Untitled Page</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>

        <%- -<asp:Label ID=”texto” runat=”server”></asp:Label>- -%>

<asp:TextBox ID=”texto” runat=”server”></asp:TextBox>
</div>
</form>
</body>
</html>

 

Como saber si un número es par o impar en C#

c-sharp imagen

Hay un algorítmo muy fácil de hacer que nos ayudará en caso de necesitar saber si un número es par o impar, para el programa que estemos desarrollando.

Utilizaremos el símbolo ‘%‘ que en C# nos da como resultado el resto de la división que hagamos. Lo vemos más claro con el código del ejemplo:

public bool EsPar (int numero)
{
if((numero % 2) == 0)
{
return true;
}else
{
return false;
}
}

Como vemos en la función anterior, le pasamos a la función el número que queremos comprobar si es par o no. Dentro de la función utilizamos el símbolo ‘%’ para dividir el número entre 2. El resto sería el resultado de esa operación. Para nuestra función si el resto es 0 el número es múltiplo de 2 y por lo tanto es par, si diera distino de 0 sería un número impar.

Como pasar de LAB a YXZ

c-sharp imagen

Si necesitas convertir de LAB a YXZ tal vez de pueda ayudar esta función de C#, en la que le pasas los 3 valores LAB y te devuelve una lista con los 3 valores YXZ .

public List<Double> mtConvertirLabToXYZ(Double valorL, Double valorA, Double valorB)
{

Double Y = 0;
Double X = 0;
Double Z = 0;
Double auxY = 0;
Double auxX = 0;
Double auxZ = 0;

auxY = (valorL + 16) / 116;
auxX = valorA / 500 + auxY;
auxZ = auxY – valorB / 200;

if (Math.Pow(auxY, 3) > 0.008856)
{
auxY = Math.Pow(auxY, 3);
}
else
{
auxY = (auxY – 16 / 116) / 7.787;
}

if (Math.Pow(auxX, 3) > 0.008856)
{
auxX = Math.Pow(auxX, 3);
}
else
{
auxX = (auxX – 16 / 116) / 7.787;
}

if (Math.Pow(auxZ, 3) > 0.008856)
{
auxZ = Math.Pow(auxZ, 3);
}
else
{
auxZ = (auxZ – 16 / 116) / 7.787;
}

Double ref_X= 95.047 ;
Double ref_Y= 100.000;
Double ref_Z = 108.883;
X = ref_X * auxX;
Y = ref_Y * auxY;
Z = ref_Z * auxZ;

List<Double> listaXYZ = new List<double>();

listaXYZ.Add(X);
listaXYZ.Add(Y);
listaXYZ.Add(Z);
return listaXYZ;
}

Como pasar de XYZ a RGB

c-sharp imagen

Si necesitas convertir de XYZ a RGB tal vez de pueda ayudar esta funcion de C#, en la que le pasas los 3 valores XYZ y te devuelve una lista con los 3 valores RGB.

public List<Double> mtConvertorXYZToRGB(Double valorX, Double valorY, Double valorZ)
{

Double var_X = valorX / 100;
Double var_Y = valorY / 100;
Double var_Z = valorZ / 100;

Double var_R;
Double var_G;
Double var_B;

var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;

if (var_R > 0.0031308)
{
var_R = 1.055 * (Math.Pow(var_R, (1 / 2.4))) – 0.055;
}
else
{
var_R = 12.92 * var_R;
}

if (var_G > 0.0031308)
{
var_G = 1.055 * (Math.Pow(var_G, (1 / 2.4))) – 0.055;
}
else
{
var_G = 12.92 * var_R;
}

if (var_B > 0.0031308)
{
var_B = 1.055 * (Math.Pow(var_B, (1 / 2.4))) – 0.055;
}
else
{
var_B = 12.92 * var_R;
}

Double R = var_R * 255;
Double G = var_G * 255;
Double B = var_B * 255;

List<Double> listaRGB = new List<double>();
listaRGB.Add(R);
listaRGB.Add(G);
listaRGB.Add(B);
return listaRGB;
}

Como copiar una DateTable en C# (también DataRow)

c-sharp imagen

Si estás programando en .NET con lenguaje C# y necesitas copiar el contenido de una tabla (DataTable) a otra hay una forma muy sencilla de hacerlo.

Tenemos 2 DataTables:

DataTable tabla1 = new DataTable();
DataTable tabla2 = new DataTable();

Si hacemos tabla2 = tabla1 NO ES VÁLIDO, porque lo que hagamos en una tabla se reflejaría en la otra.

Podemos utilizar para copiarla lo siguiente:

//Clonamos la estructura
tabla2 = tabla1.Clone();
//Recorremos las filas de la tabla1 y las importamos en la tabla2
Foreach(DataRow dr in tabla1.Rows)
{
tabla2.ImportRow(dr);
}

Con esto tendríamos 2 tablas iguales pero sin estar vinculadas referencialmente. Problema resuelto