如何保护C#编译EXE中的SecretStrings,避免被人工读取?
如何在C#代码中保护敏感字符串不被直接读取
以下几种方案可以让敏感字符串以不可读形式存储在EXE中,且无需依赖外部文件:
1. 简单XOR加解密
适合低敏感度场景,实现成本极低,代码内即可完成:
// 通用XOR加解密方法 private static string XorCrypt(string input, string key) { char[] inputChars = input.ToCharArray(); char[] keyChars = key.ToCharArray(); char[] result = new char[inputChars.Length]; for (int i = 0; i < inputChars.Length; i++) { result[i] = (char)(inputChars[i] ^ keyChars[i % keyChars.Length]); } return new string(result); } // 使用示例:先提前用该方法加密敏感字符串,把加密结果写进代码 string encryptedUser = "n`fsl"; // 加密后的"admin" string encryptedPass = "L`{vszXlssKcxoXlmx}"; // 加密后的"NobodyShouldKnowThis" // 运行时解密 string sMyUser = XorCrypt(encryptedUser, "YourSecretKey"); string sMyPass = XorCrypt(encryptedPass, "YourSecretKey"); Login(sMyUser, sMyPass);
注意:密钥不要和加密字符串硬编码得过于明显,可拆分或做简单字符变换,避免反编译后直接配对。
2. 使用Windows DPAPI加密
依赖系统内置的数据保护API,安全性更高,加密后的内容仅能在特定环境解密:
using System.Security.Cryptography; // 解密方法(加密操作提前单独运行,把结果写进代码) private static string DecryptWithDPAPI(string encryptedBase64) { byte[] encryptedBytes = Convert.FromBase64String(encryptedBase64); // LocalMachine:仅当前机器可解密;CurrentUser:仅当前登录用户可解密 byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, null, DataProtectionScope.LocalMachine); return System.Text.Encoding.UTF8.GetString(decryptedBytes); } // 使用示例 string encryptedUser = "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA..."; // 提前加密得到的"admin" Base64串 string encryptedPass = "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA..."; // 提前加密得到的密码 Base64串 string sMyUser = DecryptWithDPAPI(encryptedUser); string sMyPass = DecryptWithDPAPI(encryptedPass); Login(sMyUser, sMyPass);
注意:加密操作只需做一次,不要把加密代码留在最终发布的程序里。
3. AES对称加密
安全性较强的标准加密方案,适合高敏感场景:
using System.Security.Cryptography; // AES解密方法(加密操作提前单独完成) private static string DecryptAES(string encryptedBase64, byte[] key, byte[] iv) { using Aes aesAlg = Aes.Create(); aesAlg.Key = key; aesAlg.IV = iv; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedBase64)); using CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); using StreamReader srDecrypt = new StreamReader(csDecrypt); return srDecrypt.ReadToEnd(); } // 使用示例 byte[] aesKey = Convert.FromBase64String("YourBase64EncodedAESKey"); byte[] aesIV = Convert.FromBase64String("YourBase64EncodedAESIV"); string encryptedUser = "EncryptedAdminBase64String"; string encryptedPass = "EncryptedPassBase64String"; string sMyUser = DecryptAES(encryptedUser, aesKey, aesIV); string sMyPass = DecryptAES(encryptedPass, aesKey, aesIV); Login(sMyUser, sMyPass);
注意:密钥和IV可拆分存储或做简单变换,降低被反编译直接获取的风险。
额外建议
没有绝对的安全,上述方案只是防止直接通过文本编辑器读取明文:
- 可配合代码混淆工具(如ConfuserEx),对加密方法、密钥等进行混淆,增加反编译难度;
- 敏感字符串在运行时解密后,尽量缩短其在内存中的留存时间,使用后及时清空。
内容的提问来源于stack exchange,提问作者Michael Hutter
相关产品推荐
相关产品推荐

