【问题标题】:AES_DECRYPT() and AES_ENCRYPT() in MySQL with Polish charactersMySQL 中带有波兰字符的 AES_DECRYPT() 和 AES_ENCRYPT()
【发布时间】:2013-01-03 02:24:48
【问题描述】:

我有一个 MySQL 数据库,它被配置为接收带有波兰语字符(例如 ą、ę、ó、ł、ń 等)的数据。

现在我想使用AES_ENCRYPT() 将带有这些波兰字符的数据发送到数据库,然后使用AES_DECRYPT() 从那里获取它们。 我的问题是我在 C# 中收到一个 byte[] 数组,它有 X 个元素,其中 X 是我收到的文本长度。每个数组元素都有一个它所代表的字符的 ASCII 码。我可以使用 Encoding Class 轻松地将其转换为文本,但我不会在输出文本中获得波兰语字符。

F。例如:

我将AES_ENCRYPT('ąąą', '123') 发送到数据库。 我得到AES_DECRYPT('sql command','123'),我得到byte[],它有3个元素,每个人都有'97'值,代表'aaa'-不是'ąąą'。 如何以允许我向我的数据库发送/获取波兰字符的方式使用AES_DECRYPT/ENCRYPT?! 或者如何从 aes_decrypt() 而不是 byte[] 获取字符串输出?

【问题讨论】:

    标签: c# mysql encryption aes


    【解决方案1】:

    使用编码转换可能会对您有所帮助。

    select convert(aes_decrypt(aes_encrypt('ąąą', 'abcdefg'), 'abcdefg') using UTF8);
    

    【讨论】:

    • 嗯,当我在 MySQL WorkBench 中执行此操作时 - 它可以工作!它有波兰语字符!但是当我在我的 C# 代码中使用 ExecuteScalar() 时,我仍然得到没有波兰字符的字符串。有任何想法吗?如何在 C# 中转换它?
    • 我认为你需要在C# Encoding.Convert中找到字符串编码方法
    • 调用 ExecuteScalar() 的结果是什么。
    • 结果是字符串但没有波兰字符。这很奇怪,因为 MySQL Wrokbench(相同的命令)正在返回带有波兰字符的字符串!
    • 加密前有没有尝试编码aes_encrypt(convert('ąąą' using UTF8), 'abcdefg')
    【解决方案2】:

    您为什么不在代码中而不是在查询中实现加密/解密?

    private static Byte[] Encrypt(String toEncrypt, Byte[] Key, Byte[] IV)
    {
        CryptoStream streamCrypto = null;
        MemoryStream streamMemory = null;
        RijndaelManaged aes = null;
        StreamWriter streamWriter = null;
    
        try
        {
            aes = new RijndaelManaged();
            aes.Key = Key;
            aes.IV = IV;
    
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
            streamMemory = new MemoryStream();
            streamCrypto = new CryptoStream(streamMemory, encryptor, CryptoStreamMode.Write);
            streamWriter = new StreamWriter(streamCrypto);
    
            streamWriter.Write(toEncrypt);
    
        }
        finally
        {
            if (streamWriter != null)
                streamWriter.Close();
    
            if (streamCrypto != null)
                streamCrypto.Close();
    
            if (streamMemory != null)
                streamMemory.Close();
    
            if (aes != null)
                aes.Clear();
        }
    
        return streamMemory.ToArray();
    }
    
    public static String Decrypt(Byte[] toDecrypt, Byte[] Key, Byte[] IV)
    {
        CryptoStream streamCrypto = null;
        MemoryStream streamMemory = null;
        RijndaelManaged aes = null;
        StreamReader streamReader = null;
        String output = null;
    
        try
        {
            aes = new RijndaelManaged();
            aes.Key = Key;
            aes.IV = IV;
    
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
    
            streamMemory = new MemoryStream(toDecrypt);
            streamCrypto = new CryptoStream(streamMemory, decryptor, CryptoStreamMode.Read);
            streamReader = new StreamReader(streamCrypto);
    
            output = streamReader.ReadToEnd();
        }
        finally
        {
            if (streamReader != null)
                streamReader.Close();
    
            if (streamCrypto != null)
                streamCrypto.Close();
    
            if (streamMemory != null)
                streamMemory.Close();
    
            if (aes != null)
                aes.Clear();
        }
    
        return output;
    }
    

    在您的代码中,您对字符串进行加密,然后将加密的数据发送到数据库:

    Byte[] encrypted = Encrypt(yourString, Key, IV);  
    

    当您从数据库中提取数据时,您只需使用以下命令取回字符串:

    String decrypted = Decrypt(dbData, Key, IV);
    

    如果您不喜欢这种方式,只需像这样使用您的查询:

    INSERT INTO mysecrets (mysecret1, mysecret2) VALUES (AES_ENCRYPT(secret1, YOUR_ENCRYPTION_KEY), AES_ENCRYPT(secret2, YOUR_ENCRYPTION_KEY))
    
    SELECT AES_DECRYPT(mysecret1, YOUR_ENCRYPTION_KEY) AS secret1, AES_DECRYPT(mysecret1, YOUR_ENCRYPTION_KEY) AS secret2 FROM mysecrets
    

    【讨论】:

    • 要做很多工作。首先,我想尝试使用 mysql 函数。
    【解决方案3】:

    您的 MySQL 数据以字符为单位,而加密则以字节为单位。您需要在加密之前将字符转换为字节,并将解密的字节转换回字符。这意味着您需要明确指定要在两端使用的字符编码,以便它们匹配。当前标准是 UTF-8,因此您应该在每一端指定它。如果 UTF-8 不起作用,那么在两端尝试一些 Microsoft 特定的字符编码。

    【讨论】:

    • 好的,现在我试试你的想法。我已经使用byte[] bytes=Encoding.UTF8.GetBytes(string);将字符串转换为字节[],但是如何将这些字节正确插入到我的 varchar() 列中?
    • 我不是 MySQL 专家,但字节不是 字符。您需要一个包含二进制数据、varbytes (?)、BLOB 或类似内容的列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2018-08-05
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    相关资源
    最近更新 更多