byte[] additionalEntropy = { 9, 8, 7, 6, 5 }; Func<string, string> GetSecureEnvVar = (varName) => { var val = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User); if (!string.IsNullOrEmpty(val)) { try { val = Encoding.UTF8.GetString( ProtectedData.Unprotect(Convert.FromBase64String(val), additionalEntropy, DataProtectionScope.CurrentUser)); return val; } catch { Console.WriteLine("非有效加密格式,請重新輸入"); } } Console.Write($"請設定[{varName}]:"); val = Console.ReadLine() ?? string.Empty; //加密後存入環境變數 var enc = Convert.ToBase64String( ProtectedData.Protect(Encoding.UTF8.GetBytes(val), additionalEntropy, DataProtectionScope.CurrentUser)); Environment.SetEnvironmentVariable(varName, enc, EnvironmentVariableTarget.User); return val;
拷貝了作法實際跑了一次確實可以 Work,缺點是 ProtectedData 這個 Class 是 Windows Data Protection API (DPAPI) 的一個封裝,專門為 Windows 設計。它使用 Windows 用戶帳戶相關的加密密鑰,因此在其他操作系統上不可用,並且EnvironmentVariableTarget.User 在所有主要操作系統上都存在,但 User 級別的環境變量主要是 Windows 的概念。
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV)) using (var ms = new System.IO.MemoryStream()) { using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) using (var sw = new System.IO.StreamWriter(cs)) { sw.Write(plainText); } return Convert.ToBase64String(ms.ToArray()); } } }
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV)) using (var ms = new System.IO.MemoryStream(Convert.FromBase64String(cipherText))) using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) using (var sr = new System.IO.StreamReader(cs)) { return sr.ReadToEnd(); } } }