You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6 C# Encoding.UTF8.GetString转换加密字节数组返回Unicode乱码问题

问题根源

  • 你不能直接用Encoding.UTF8.GetString()转换任意二进制字节数组:ProtectedData.Protect()返回的加密结果是无规则的二进制数据,不符合UTF8编码规范,强制转换会出现不可逆的字符损坏、乱码,你再把字符串转回字节数组时得到的内容和原加密数组完全不一致,自然会导致解密失败、程序崩溃。
  • PrintValues方法中直接把字节强制转为char打印,加密后的字节大多是不可见控制字符,也会输出乱码。

修复方案

把加密后的二进制字节数组转为Base64字符串再存入环境变量,Base64可以用可打印的标准ASCII字符无损表示任意二进制数据,不会出现编码丢失。
修复后的代码如下:

using System;
using System.Security.Cryptography;
using System.Text;

namespace Crrypto
{
    class Program
    {
        static byte[] s_additionalEntropy = Encoding.UTF8.GetBytes("hello");
        static void Main(string[] args)
        {
            // 创建待加密的字节数组
            byte[] secret = Encoding.UTF8.GetBytes("password");
            
            // 加密数据
            byte[] encryptedSecret = Protect(secret);
            // 转Base64字符串再存环境变量,不要用UTF8转
            string store = Convert.ToBase64String(encryptedSecret);
            Environment.SetEnvironmentVariable("passwordLA", store);
            
            Console.WriteLine("加密后的字节数组(十六进制表示):");
            PrintValues(encryptedSecret);

            // 从环境变量读取并解密
            string secretFromEnv = Environment.GetEnvironmentVariable("passwordLA");
            // 把Base64字符串转回字节数组再解密
            byte[] loaded = Convert.FromBase64String(secretFromEnv);
            byte[] originalData = Unprotect(loaded);
            
            Console.WriteLine($"{Environment.NewLine}解密后的原始数据:");
            PrintValues(originalData);
            // 可以直接转字符串查看原始密码
            Console.WriteLine($"原始密码明文:{Encoding.UTF8.GetString(originalData)}");
        }

        public static byte[] Protect(byte[] data)
        {
            try
            {
                return ProtectedData.Protect(data, s_additionalEntropy, DataProtectionScope.CurrentUser);
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("加密失败,发生错误:");
                Console.WriteLine(e.ToString());
                return null;
            }
        }

        public static byte[] Unprotect(byte[] data)
        {
            try
            {
                return ProtectedData.Unprotect(data, s_additionalEntropy, DataProtectionScope.CurrentUser);
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("解密失败,发生错误:");
                Console.WriteLine(e.ToString());
                return null;
            }
        }

        // 修改PrintValues,打印字节的十六进制值,不要强转char
        public static void PrintValues(Byte[] myArr)
        {
            foreach (Byte b in myArr)
            {
                Console.Write($"{b:X2} ");
            }
            Console.WriteLine();
        }
    }
}

内容的提问来源于stack exchange,提问作者TheLegend27

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:54:02