【问题标题】:need help Converting laravel Crypt to C#需要帮助将 laravel Crypt 转换为 C#
【发布时间】:2016-02-17 03:11:32
【问题描述】:
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# php encryption laravel-5.1


    【解决方案1】:

    将填充更改为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】:

    由于Laravel使用base64:在APP_KEY中,C#实现laravel加密的代码略有改动:

    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)));
        }
    

    使用 $key 的 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;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多