нужна помощь в преобразовании laravel Crypt в C#


public static string Encrypt(this string plainText)
{
    RijndaelManaged aes = new RijndaelManaged();
    aes.KeySize = 256;
    aes.BlockSize = 128;
    aes.Padding = PaddingMode.Zeros;
    aes.Mode = CipherMode.CBC;

    aes.Key = Encoding.Default.GetBytes(key);
    aes.GenerateIV();

    ICryptoTransform AESEncrypt = aes.CreateEncryptor(aes.Key, aes.IV);
    byte[] buffer = Encoding.ASCII.GetBytes(plainText);

    String encryptedText = Convert.ToBase64String(Encoding.Default.GetBytes(Encoding.Default.GetString(AESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length))));

    String mac = "";
    using (var hmacsha256 = new HMACSHA256(Encoding.Default.GetBytes(key)))
    {
        hmacsha256.ComputeHash(Encoding.Default.GetBytes(Convert.ToBase64String(aes.IV) + encryptedText));

        mac = ByteArrToString(hmacsha256.Hash);
    }

    var keyValues = new Dictionary<string, object>
    {
        { "iv", Convert.ToBase64String(aes.IV) },
        { "value", encryptedText },
        { "mac", mac },
    };
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    //return serializer.Serialize(keyValues);
    return Convert.ToBase64String(Encoding.ASCII.GetBytes(serializer.Serialize(keyValues)));
}



public static string Decrypt(this string cipherText)
{
    RijndaelManaged aes = new RijndaelManaged();
    aes.KeySize = 256;
    aes.BlockSize = 128;
    aes.Padding = PaddingMode.Zeros;
    aes.Mode = CipherMode.CBC;

    aes.Key = Encoding.Default.GetBytes(key);

    dynamic payload = GetJsonPayload(cipherText);

    //return Encoding.Default.GetString(Convert.FromBase64String(cipherText));

    //cipherText = Convert.ToBase64String(Encoding.Default.GetBytes(payload["value"]));
    aes.IV = Convert.FromBase64String(payload["iv"]);

    ICryptoTransform AESDecrypt = aes.CreateDecryptor(aes.Key, aes.IV);
    byte[] buffer = Convert.FromBase64String(payload["value"]);

    return (Encoding.Default.GetString(AESDecrypt.TransformFinalBlock(buffer, 0, buffer.Length))).ToString();
}

Https://github.com/laravel/framework/blob/5.1/src/Illuminate/Encryption/Encrypter.php

Я использую приведенный выше код, он работает, когда я расшифровываю что-либо из Laravel. проблема в том, что когда я шифрую строку из c#, я не могу расшифровать ее в php.

Иногда после расшифрованного текста появляются "значения". шифрование выходных данных и их расшифровка в php работает.

C# screenshot

Author: Joe, 2015-11-16

2 answers

Изменение отступа на PaddingMode.PKCS7 работает! в случае, если другим людям это все еще нужно, полный код размещен ниже.

public static string Encrypt(this string plainText)
{
    RijndaelManaged aes = new RijndaelManaged();
    aes.KeySize = 256;
    aes.BlockSize = 128;
    aes.Padding = PaddingMode.PKCS7;
    aes.Mode = CipherMode.CBC;

    aes.Key = Encoding.Default.GetBytes(key);
    aes.GenerateIV();

    ICryptoTransform AESEncrypt = aes.CreateEncryptor(aes.Key, aes.IV);
    byte[] buffer = Encoding.ASCII.GetBytes(plainText);

    String encryptedText = Convert.ToBase64String(Encoding.Default.GetBytes(Encoding.Default.GetString(AESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length))));

    String mac = "";
    using (var hmacsha256 = new HMACSHA256(Encoding.Default.GetBytes(key)))
    {
        hmacsha256.ComputeHash(Encoding.Default.GetBytes(Convert.ToBase64String(aes.IV) + encryptedText));

        mac = ByteArrToString(hmacsha256.Hash);
    }

    var keyValues = new Dictionary<string, object>
    {
        { "iv", Convert.ToBase64String(aes.IV) },
        { "value", encryptedText },
        { "mac", mac },
    };
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    //return serializer.Serialize(keyValues);
    return Convert.ToBase64String(Encoding.ASCII.GetBytes(serializer.Serialize(keyValues)));
}



public static string Decrypt(this string cipherText)
{
    RijndaelManaged aes = new RijndaelManaged();
    aes.KeySize = 256;
    aes.BlockSize = 128;
    aes.Padding = PaddingMode.PKCS7;
    aes.Mode = CipherMode.CBC;

    aes.Key = Encoding.Default.GetBytes(key);

    dynamic payload = GetJsonPayload(cipherText);

    //return Encoding.Default.GetString(Convert.FromBase64String(cipherText));

    //cipherText = Convert.ToBase64String(Encoding.Default.GetBytes(payload["value"]));
    aes.IV = Convert.FromBase64String(payload["iv"]);

    ICryptoTransform AESDecrypt = aes.CreateDecryptor(aes.Key, aes.IV);
    byte[] buffer = Convert.FromBase64String(payload["value"]);

    return (Encoding.Default.GetString(AESDecrypt.TransformFinalBlock(buffer, 0, buffer.Length))).ToString();
}
 2
Author: Joe, 2015-11-23 03:40:59

Поскольку Laravel использует base64: в APP_KEY код для шифрования laravel в C# немного изменился:

private string encrypt(string plainText)
    {
        RijndaelManaged aes = new RijndaelManaged();
        aes.KeySize = 256;
        aes.BlockSize = 128;
        aes.Padding = PaddingMode.PKCS7;
        aes.Mode = CipherMode.CBC;

        aes.Key = Convert.FromBase64String(key);
        aes.GenerateIV();

        ICryptoTransform AESEncrypt = aes.CreateEncryptor(aes.Key, aes.IV);
        byte[] buffer = Encoding.ASCII.GetBytes(phpSerialize(plainText));

        String encryptedText = Convert.ToBase64String(Encoding.Default.GetBytes(Encoding.Default.GetString(AESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length))));

        String mac = "";
        using (var hmacsha256 = new HMACSHA256(Convert.FromBase64String(key)))
        {
            hmacsha256.ComputeHash(Encoding.Default.GetBytes(Convert.ToBase64String(aes.IV) + encryptedText));

            mac = ByteToString(hmacsha256.Hash);
        }

        var keyValues = new Dictionary<string, object>
        {
            { "iv", Convert.ToBase64String(aes.IV) },
            { "value", encryptedText },
            { "mac", mac },
        };
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        //return serializer.Serialize(keyValues);
        return Convert.ToBase64String(Encoding.ASCII.GetBytes(serializer.Serialize(keyValues)));
    }

С $ключом APP_KEY без части "base64:" и

private string phpSerialize(String value)
    {
        return "s:" + value.Length + ":" + "\"" + value + "\";";
    }

Для сериализации (только для строк, но для этого существуют полные библиотеки)

И, наконец, функция ByteToString:

private string ByteToString(byte[] buff)
    {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++)
            sbinary += buff[i].ToString("x2"); /* hex format */
        return sbinary;
    }
 0
Author: Reyske, 2016-05-04 15:12:33