Pregunta

ACTUALIZADO

Me han hecho los cambios en el código C # por lo que utiliza un tamaño de bloque de 256. Pero ahora el hola mundo parece este http://pastebin.com/5sXhMV11 y yo puedo entender por qué debería utilizar con rtrim () para obtener paseo del lío al final.

Además, cuando usted dice que el IV debe ser al azar, por esta Qué quiere decir no utilice el mismo IV más de una vez, o es la forma en que he codificado mal?

Gracias de nuevo!

Hola,

Estoy tratando de descifrar una cadena con PHP que se ha cifrado en C #. Parece que no puedo obtener PHP para descifrarlo usando mcrypt y podría hacer con un poco de ayuda por favor. Me sale el siguiente error con php así que supongo que no estoy estableciendo el IV correctamente.

Error: El parámetro IV debe ser tan largo como el tamaño de bloque

Ambas funciones utilizan el mismo sistema de cifrado, clave, IV y en modo CBC:

texto cifrado desde C # = == UmzUCnAzThH0nMkIuMisqg
clave 32 de largo = qwertyuiopasdfghjklzxcvbnmqwerty
iv 16 = 1234567890123456 largo

C #

    public static string EncryptString(string message, string KeyString, string IVString)
    {
        byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
        byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);

        string encrypted = null;
        RijndaelManaged rj = new RijndaelManaged();
        rj.Key = Key;
        rj.IV = IV;
        rj.Mode = CipherMode.CBC;

        try
        {
            MemoryStream ms = new MemoryStream();

            using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
            {
                using (StreamWriter sw = new StreamWriter(cs))
                {
                    sw.Write(message);
                    sw.Close();
                }
                cs.Close();
            }
            byte[] encoded = ms.ToArray();
            encrypted = Convert.ToBase64String(encoded);

            ms.Close();
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
            return null;
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: {0}", e.Message);
        }
        finally
        {
            rj.Clear();
        }

        return encrypted;
    }

PHP

var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
var $mcrypt_mode = MCRYPT_MODE_CBC;

function decrypt($key, $iv, $encrypted)
{
    $encrypted = base64_decode($encrypted);

    $decrypted = rtrim(mcrypt_decrypt($this->mcrypt_cipher, $key, $encrypted, $this->mcrypt_mode, $iv), "\0");;
    return $decrypted;
}

Gracias

¿Fue útil?

Solución

Si desea utilizar Rijndael256 en su aplicación C # tiene que configurar el tamaño de bloque de 256.

RijndaelManaged rj = new RijndaelManaged();
rj.BlockSize = 256;

Y a continuación, el iv tiene que ser de 256 bits de largo también.
ver SymmetricAlgorithm.BlockSize Propiedad


O al revés: En la actualidad su aplicación C # utiliza Rijndael128 y así debe su script php.

<?php
class Foo {
  protected $mcrypt_cipher = MCRYPT_RIJNDAEL_128;
  protected $mcrypt_mode = MCRYPT_MODE_CBC;

  public function decrypt($key, $iv, $encrypted)
  {
    $iv_utf = mb_convert_encoding($iv, 'UTF-8');
    return mcrypt_decrypt($this->mcrypt_cipher, $key, base64_decode($encrypted), $this->mcrypt_mode, $iv_utf);
  }
}



$encrypted = "UmzUCnAzThH0nMkIuMisqg==";
$key = "qwertyuiopasdfghjklzxcvbnmqwerty";
$iv = "1234567890123456";

$foo = new Foo;
echo $foo->decrypt($key, $iv, $encrypted);

impresiones hello world

Otros consejos

Cifrar usando PHP;

/Generate public key for encrytion
$path = "keys/";

    $crt = openssl_x509_read(file_get_contents($path."cert.crt"));
    $publickey = openssl_get_publickey($crt);

    //Encrypt using public key
    openssl_public_encrypt($source, $crypted, $publickey);

    //openssl_private_encrypt($source, $crypted, $privkey);
    echo base64_encode($crypted);

Decrypt usando C #

    X509Certificate2 x509cert = new X509Certificate2(pKeyFilename);
    RSACryptoServiceProvider.UseMachineKeyStore = false;
    RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)x509cert.PrivateKey;                

    byte[] decrypted = crypt.Decrypt(Convert.FromBase64String(data), false);
    return ASCIIEncoding.UTF8.GetString(decrypted);

donde pKeyFilename es un archivo de intercambio de información personal creada con el cert.crt archivo de certificado. Este ejemplo utiliza un cifrado AES-256.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top