在C#解密AES CBC 256加密

时间:2016-09-08 11:37:41

标签: c# c++ encryption aes

我想在C#中加密并在c ++中解密,但我有一些编码问题:

示例变量:

键:g OtIPaL ver-vS5UAnJbPqsDZSf,yJ1 IVString:g OtIPaL ver-vS5

我的c#代码:

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

        string encrypted = null;
        RijndaelManaged rj = new RijndaelManaged();
        rj.Key = Key;
        rj.IV = IV;
        rj.Mode = CipherMode.CBC;
        rj.Padding = PaddingMode.PKCS7;
        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;
    }

当我尝试加密并且我的密钥有些不是ASCII字符时 - 字节数超过字符串的长度。

我如何使用编码?在C ++中,我使用EVP(默认填充是PKCS7)。

static string decryptEX(string KS, string ctext)
{
EVP_CIPHER_CTX* ctx;
ctx = EVP_CIPHER_CTX_new();
string IV = KS.substr(0, 16);
int rc = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (byte*)&KS[0], (byte*)&IV[0]);
std::string rtext;
rtext.resize(ctext.size());

int out_len1 = (int)rtext.size();
rc = EVP_DecryptUpdate(ctx, (byte*)&rtext[0], &out_len1, (const byte*)&ctext[0], (int)ctext.size());


int out_len2 = (int)rtext.size() - out_len1;
rc = EVP_DecryptFinal_ex(ctx, (byte*)&rtext[0] + out_len1, &out_len2);
try
{
    rtext.resize(out_len1 + out_len2);
}
catch (exception e)
{

}
return rtext;

}

1 个答案:

答案 0 :(得分:1)

致电

byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString.Substring(0,32));

失败,因为该字符串中没有32个字符。是的,如果字符串编码为UTF8,则会有32个字节。但是Substring需要一个字符数。

将该行更改为

byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);

给出一个32字节的长密钥。

由于您无法获得KeyString的正确输入,因此您可以在之后验证您的密钥长度足够长。

byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);
if (Key.Length < 32)
   throw new KeyLengthException("some useful info as to why this was thrown"); // or some other appropriate Exception type you create or resuse.

如果我在假设您需要哪些密钥,IV和块大小时是正确的,那么这应该是您所需要的:

    public static string EncryptString(string message, string KeyString, string IVString)
    {
        byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString).Take(32).ToArray();
        if (Key.Length < 32)
            throw new Exception("KeyString not at least 32 bytes.");
        byte[] IV = UTF8Encoding.UTF8.GetBytes(IVString).Take(16).ToArray();
        if (Key.Length < 32)
            throw new Exception("IVString not at least 16 bytes.");
        string encrypted = null;
        RijndaelManaged rj = new RijndaelManaged();
        rj.KeySize = 128;
        rj.BlockSize = 128;
        rj.Key = Key;
        rj.IV = IV;
        rj.Mode = CipherMode.CBC;
        rj.Padding = PaddingMode.PKCS7;
        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;
    }