自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在Asp.NET Core中如何優(yōu)雅的管理用戶機(jī)密數(shù)據(jù)

開發(fā) 架構(gòu)
在早期VB/VB.NET時(shí)代,經(jīng)常使用.ini文件來進(jìn)行配置管理;而在.NET FX開發(fā)中,我們則傾向于使用web.config文件,通過配置appsetting的配置節(jié)來處理;而在.NET Core開發(fā)中,我們有了新的基于json格式的appsetting.json文件。

[[428220]]

本文轉(zhuǎn)載自微信公眾號(hào)「DotNET技術(shù)圈」,作者鄒溪源。轉(zhuǎn)載本文請(qǐng)聯(lián)系DotNET技術(shù)圈公眾號(hào)。

背景

回顧

在軟件開發(fā)過程中,使用配置文件來管理某些對(duì)應(yīng)用程序運(yùn)行中需要使用的參數(shù)是常見的作法。

在早期VB/VB.NET時(shí)代,經(jīng)常使用.ini文件來進(jìn)行配置管理;而在.NET FX開發(fā)中,我們則傾向于使用web.config文件,通過配置appsetting的配置節(jié)來處理;而在.NET Core開發(fā)中,我們有了新的基于json格式的appsetting.json文件。

無論采用哪種方式,其實(shí)配置管理從來都是一件看起來簡(jiǎn)單,但影響非常深遠(yuǎn)的基礎(chǔ)性工作。尤其是配置的安全性,貫穿應(yīng)用程序的始終,如果沒能做好安全性問題,極有可能會(huì)給系統(tǒng)帶來不可控的風(fēng)向。

源代碼比配置文件安全么?

有人以為把配置存放在源代碼中,可能比存放在明文的配置文件中似乎更安全,其實(shí)是“皇帝的新裝”。

在前不久,筆者的一位朋友就跟我說了一段故事:他說一位同事在離職后,直接將曾經(jīng)寫過的一段代碼上傳到github的公共倉(cāng)庫,而這段代碼中包含了某些涉及到原企業(yè)的機(jī)密數(shù)據(jù),還好被github的安全機(jī)制提前發(fā)現(xiàn)而及時(shí)終止了該行為,否則后果不堪設(shè)想。

于是,筆者順手查了一下由于有意或無意泄露企業(yè)機(jī)密,造成企業(yè)損失的案例,發(fā)現(xiàn)還真不少。例如大疆前員工通過 Github 泄露公司源代碼,被罰 20 萬、獲刑半年[1] 這起案件,也是一個(gè)典型的案例。

該員工離職后,將包含關(guān)鍵配置信息的源代碼上傳到github的公共倉(cāng)庫,被黑客利用,使得大量用戶私人數(shù)據(jù)被黑客獲取,該前員工最終被刑拘。

大疆前員工通過Github泄露公司源代碼,被罰20萬、獲刑半年

圖片來源: http://www.digitalmunition.com/WhyIWalkedFrom3k.pdf[2]

大部分IT公司都會(huì)在入職前進(jìn)行背景調(diào)查,而一旦有案底,可能就已經(jīng)與許多IT公司無緣;即便是成為創(chuàng)業(yè)者,也可能面臨無法跟很多正規(guī)企業(yè)合作的問題。

小結(jié)

所以,安全性問題不容小覷,哪怕時(shí)間再忙,也不要急匆匆的就將數(shù)據(jù)庫連接字符串或其他包含敏感信息的內(nèi)容輕易的記錄在源代碼或配置文件中。在這個(gè)點(diǎn)上,一旦出現(xiàn)問題,往往都是非常嚴(yán)重的問題。

如何實(shí)現(xiàn)

在.NET FX時(shí)代,我們可以使用對(duì)web.config文件的關(guān)鍵配置節(jié)進(jìn)行加密的方式,來保護(hù)我們的敏感信息,在.NET Core中,自然也有這些東西,接下來我將簡(jiǎn)述在開發(fā)環(huán)境和生產(chǎn)環(huán)境下不同的配置加密手段,希望能夠給讀者帶來啟迪。

開發(fā)環(huán)境

在開發(fā)環(huán)境下,我們可以使用visual studio 工具提供的用戶機(jī)密管理器,只需0行代碼,即可輕松完成關(guān)鍵配置節(jié)的處理。

機(jī)密管理器概述

根據(jù)微軟官方文檔[3] 的描述:

ASP.NET Core 機(jī)密管理器[4]工具提供了開發(fā)過程中在源代碼外部保存機(jī)密的另一種方法 。若要使用機(jī)密管理器工具,請(qǐng)?jiān)陧?xiàng)目文件中安裝包 Microsoft.Extensions.Configuration.SecretManager 。如果該依賴項(xiàng)存在并且已還原,則可以使用 dotnet user-secrets 命令來通過命令行設(shè)置機(jī)密的值。這些機(jī)密將存儲(chǔ)在用戶配置文件目錄中的 JSON 文件中(詳細(xì)信息隨操作系統(tǒng)而異),與源代碼無關(guān)。

機(jī)密管理器工具設(shè)置的機(jī)密是由使用機(jī)密的項(xiàng)目的 UserSecretsId 屬性組織的。因此,必須確保在項(xiàng)目文件中設(shè)置 UserSecretsId 屬性,如下面的代碼片段所示。默認(rèn)值是 Visual Studio 分配的 GUID,但實(shí)際字符串并不重要,只要它在計(jì)算機(jī)中是唯一的。

  1. <PropertyGroup> 
  2.    <UserSecretsId>UniqueIdentifyingString</UserSecretsId> 
  3. </PropertyGroup>  

 

Secret Manager工具允許開發(fā)人員在開發(fā)ASP.NET Core應(yīng)用程序期間存儲(chǔ)和檢索敏感數(shù)據(jù)。敏感數(shù)據(jù)存儲(chǔ)在與應(yīng)用程序源代碼不同的位置。

由于Secret Manager將秘密與源代碼分開存儲(chǔ),因此敏感數(shù)據(jù)不會(huì)提交到源代碼存儲(chǔ)庫。但機(jī)密管理器不會(huì)對(duì)存儲(chǔ)的敏感數(shù)據(jù)進(jìn)行加密,因此不應(yīng)將其視為可信存儲(chǔ)。

敏感數(shù)據(jù)作為鍵值對(duì)存儲(chǔ)在JSON文件中。最好不要在開發(fā)和測(cè)試環(huán)境中使用生產(chǎn)機(jī)密。查看引文[5]。

存放位置

在windows平臺(tái)下,機(jī)密數(shù)據(jù)的存放位置為:

  1. %APPDATA%\Microsoft\UserSecrets\\secrets.json 

而在Linux/MacOs平臺(tái)下,機(jī)密數(shù)據(jù)的存放位置為:

  1. ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json 

在前面的文件路徑中, `user_secrets_id`將替換UserSecretsId為.csproj

文件中指定的值。

在Windows環(huán)境下使用機(jī)密管理器

在windows下,如果使用Visual Studio2019作為主力開發(fā)環(huán)境,只需在項(xiàng)目右鍵單擊,選擇菜單【管理用戶機(jī)密】,即可添加用戶機(jī)密數(shù)據(jù)。

在管理用戶機(jī)密數(shù)據(jù)中,添加的配置信息和傳統(tǒng)的配置信息沒有任何區(qū)別。

  1. "ConnectionStrings": { "Default""Server=xxx;Database=xxx;User ID=xxx;Password=xxx;" } } 

我們同樣也可以使用IConfiguration的方式、IOptions的方式,進(jìn)行配置的訪問。

在非Windows/非Visual Studio環(huán)境下使用機(jī)密管理器

完成安裝dotnet-cli后,在控制臺(tái)輸入

  1. dotnet user-secrets init 

前面的命令將在UserSecretsId .csproj 文件的PropertyGroup中添加

.csproj

一個(gè)元素。 UserSecretsId是對(duì)項(xiàng)目是唯一的Guid值。

  1. <PropertyGroup>   
  2.      <TargetFramework>netcoreapp3.1</TargetFramework> 
  3.     <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>  
  4.  </PropertyGroup>  

 

設(shè)置機(jī)密

  1. dotnet user-secrets set "Movies:ServiceApiKey" "12345"  

列出機(jī)密

  1. dotnet user-secrets list 

刪除機(jī)密

  1. dotnet user-secrets remove "Movies:ConnectionString"  

清除所有機(jī)密

  1. dotnet user-secrets clear 

生產(chǎn)環(huán)境

機(jī)密管理器為開發(fā)者在開發(fā)環(huán)境下提供了一種保留機(jī)密數(shù)據(jù)的方法,但在開發(fā)環(huán)境下是不建議使用的,如果想在生產(chǎn)環(huán)境下,對(duì)機(jī)密數(shù)據(jù)進(jìn)行保存該怎么辦?

按照微軟官方文檔的說法,推薦使用Azure Key Vault [6] 來保護(hù)機(jī)密數(shù)據(jù),但。。我不是貴云的用戶(當(dāng)然,買不起貴云不是貴云太貴,而是我個(gè)人的問題[手動(dòng)狗頭]圖片圖片)。

其次,與Azure Key Valut類似的套件,例如其他云,差不多都有,所以都可以為我們所用。

但。。如果您如果跟我一樣,不想通過第三方依賴的形式來解決這個(gè)問題,那不如就用最簡(jiǎn)單的辦法,例如AES加密。

使用AES加密配置節(jié)

該方法與平時(shí)使用AES對(duì)字符串進(jìn)行加密和解密的方法并無區(qū)別,此處從略。

使用數(shù)據(jù)保護(hù)Api(DataProtect Api實(shí)現(xiàn))

在平時(shí)開發(fā)過程中,能夠動(dòng)手?jǐn)]AES加密是一種非常好的習(xí)慣,而微軟官方提供的數(shù)據(jù)保護(hù)API則將這個(gè)過程進(jìn)一步簡(jiǎn)化,只需調(diào)Api即可完成相應(yīng)的數(shù)據(jù)加密操作。

關(guān)于數(shù)據(jù)保護(hù)api, Savorboard[7] 大佬曾經(jīng)寫過3篇博客討論這個(gè)技術(shù)問題,大家可以參考下面的文章來獲取信息。

(接下來我要貼代碼了,如果沒興趣,請(qǐng)出門左拐,代碼不能完整運(yùn)行,查看代碼來源[11])

首先,注入配置項(xiàng)

  1. public static IServiceCollection AddProtectedConfiguration(this IServiceCollection services, string directory) 
  2.         { 
  3.             services 
  4.                 .AddDataProtection() 
  5.                 .PersistKeysToFileSystem(new DirectoryInfo(directory)) 
  6.                 .UseCustomCryptographicAlgorithms(new ManagedAuthenticatedEncryptorConfiguration 
  7.                 { 
  8.                     EncryptionAlgorithmType = typeof(Aes), 
  9.                     EncryptionAlgorithmKeySize = 256, 
  10.                     ValidationAlgorithmType = typeof(HMACSHA256) 
  11.                 }); 
  12.             ; 
  13.  
  14.             return services; 
  15.         } 

其次,實(shí)現(xiàn)對(duì)配置節(jié)的加/解密。(使用AES算法的數(shù)據(jù)保護(hù)機(jī)制)

  1. public class ProtectedConfigurationSection : IConfigurationSection 
  2.     { 
  3.         private readonly IDataProtectionProvider _dataProtectionProvider; 
  4.         private readonly IConfigurationSection _section; 
  5.         private readonly Lazy<IDataProtector> _protector; 
  6.  
  7.         public ProtectedConfigurationSection( 
  8.             IDataProtectionProvider dataProtectionProvider, 
  9.             IConfigurationSection section
  10.         { 
  11.             _dataProtectionProvider = dataProtectionProvider; 
  12.             _section = section
  13.  
  14.             _protector = new Lazy<IDataProtector>(() => dataProtectionProvider.CreateProtector(section.Path)); 
  15.         } 
  16.  
  17.         public IConfigurationSection GetSection(string key
  18.         { 
  19.             return new ProtectedConfigurationSection(_dataProtectionProvider, _section.GetSection(key)); 
  20.         } 
  21.  
  22.         public IEnumerable<IConfigurationSection> GetChildren() 
  23.         { 
  24.             return _section.GetChildren() 
  25.                 .Select(x => new ProtectedConfigurationSection(_dataProtectionProvider, x)); 
  26.         } 
  27.  
  28.         public IChangeToken GetReloadToken() 
  29.         { 
  30.             return _section.GetReloadToken(); 
  31.         } 
  32.  
  33.         public string this[string key
  34.         { 
  35.             get => GetProtectedValue(_section[key]); 
  36.             set => _section[key] = _protector.Value.Protect(value); 
  37.         } 
  38.  
  39.         public string Key => _section.Key
  40.         public string Path => _section.Path; 
  41.  
  42.         public string Value 
  43.         { 
  44.             get => GetProtectedValue(_section.Value); 
  45.             set => _section.Value = _protector.Value.Protect(value); 
  46.         } 
  47.  
  48.         private string GetProtectedValue(string value) 
  49.         { 
  50.             if (value == null
  51.                 return null
  52.  
  53.             return _protector.Value.Unprotect(value); 
  54.         } 
  55.     } 

再次,在使用前,先將待加密的字符串轉(zhuǎn)換成BASE64純文本,然后再使用數(shù)據(jù)保護(hù)API對(duì)數(shù)據(jù)進(jìn)行處理,得到處理后的字符串。

  1. private readonly IDataProtectionProvider _dataProtectorTokenProvider; 
  2. public TokenAuthController( IDataProtectionProvider dataProtectorTokenProvider) 
  3. [Route("encrypt"), HttpGet, HttpPost] 
  4. public string Encrypt(string section, string value) 
  5.      var protector = _dataProtectorTokenProvider.CreateProtector(section); 
  6.      return protector.Protect(value); 

再替換配置文件中的對(duì)應(yīng)內(nèi)容。

  1.   "ConnectionStrings": { 
  2.     "Default""此處是加密后的字符串" 
  3.   } 

然后我們就可以按照平時(shí)獲取IOptions的方式來獲取了。

問題

公眾號(hào)【DotNET騷操作】號(hào)主【周杰】同學(xué)提出以下觀點(diǎn):

1、在生產(chǎn)環(huán)境下,使用AES加密,其實(shí)依然是一種不夠安全的行為,充其量也就能忽悠下產(chǎn)品經(jīng)理,畢竟幾條簡(jiǎn)單的語句,就能把機(jī)密數(shù)據(jù)dump出來。

也許在這種情況下,我們應(yīng)該優(yōu)先考慮accessKeyId/accessSecret,盡量通過設(shè)置多級(jí)子賬號(hào),通過授權(quán)Api的機(jī)制來管理機(jī)密數(shù)據(jù),而不是直接暴露類似于數(shù)據(jù)庫連接字符串這樣的關(guān)鍵配置信息。另外,應(yīng)該定期更換數(shù)據(jù)庫的密碼,盡量將類似的問題可能造成的風(fēng)險(xiǎn)降到最低。數(shù)據(jù)保護(hù)api也提供的類似的機(jī)制,使得開發(fā)者能夠輕松的管理機(jī)密數(shù)據(jù)的時(shí)效性問題。

2、配置文件放到CI/CD中,發(fā)布的時(shí)候在CI/CD中進(jìn)行組裝,然后運(yùn)維只是負(fù)責(zé)管理CI/CD的賬戶信息,而最高機(jī)密數(shù)據(jù),則由其他人負(fù)責(zé)配置。

嗯,我完全同意他的第二種做法,另外考慮到由于運(yùn)維同樣有可能會(huì)有意無意泄露機(jī)密數(shù)據(jù),所以如果再給運(yùn)維配備一本《刑法》,并讓他日常補(bǔ)習(xí)【侵犯商業(yè)秘密罪】相關(guān)條款,這個(gè)流程就更加閉環(huán)了。

結(jié)語

本文簡(jiǎn)述了在.NET Core中,如何在開發(fā)環(huán)境下使用用戶機(jī)密管理器、在生產(chǎn)環(huán)境下使用AES+IDataProvider的方式來保護(hù)我們的用戶敏感數(shù)據(jù)。由于時(shí)間倉(cāng)促,如有考慮不周之處,還請(qǐng)各位大佬批評(píng)指正。

References

[1] 大疆前員工通過 Github 泄露公司源代碼,被罰 20 萬、獲刑半年: https://www.infoq.cn/article/RZzfel1m6-h8pSK8TTC9

[2]http://www.digitalmunition.com/WhyIWalkedFrom3k.pdf: http://www.digitalmunition.com/WhyIWalkedFrom3k.pdf

[3] 微軟官方文檔: https://docs.microsoft.com/zh-cn/dotnet/architecture/microservices/secure-net-microservices-web-applications/developer-app-secrets-storage

[4] 機(jī)密管理器: https://docs.microsoft.com/zh-cn/aspnet/core/security/app-secrets#secret-manager

[5] 查看引文: https://nvisium.com/blog/2019/05/02/Dev-Secrets-and-the-ASP-NET-Core-Secret-Manager.html

[6] Azure Key Vault : https://docs.microsoft.com/zh-cn/dotnet/architecture/microservices/secure-net-microservices-web-applications/azure-key-vault-protects-secrets

[7] Savorboard: https://home.cnblogs.com/u/savorboard/

[8] ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection 集群場(chǎng)景)【上】: https://www.cnblogs.com/savorboard/p/dotnetcore-data-protection.html

[9] ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection 集群場(chǎng)景)【中】: https://www.cnblogs.com/savorboard/p/dotnet-core-data-protection.html

[10] ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection 集群場(chǎng)景)【下】: https://www.cnblogs.com/savorboard/p/dotnetcore-data-protected-farm.html

[11] 查看代碼: https://stackoverflow.com/questions/36062670/encrypted-configuration-in-asp-net-core

 

本文首發(fā)于溪源的個(gè)人博客:https://www.techq.xyz/2020/06/09/%E6%8A%80%E6%9C%AF/how-to-manage-user-secret-in-develop-and-production/

 

責(zé)任編輯:武曉燕 來源: DotNET技術(shù)圈
相關(guān)推薦

2024-05-21 08:14:59

代碼接口依賴注入

2024-08-12 08:15:46

2021-01-13 07:33:41

API數(shù)據(jù)安全

2021-02-19 06:54:33

配置系統(tǒng)ASP.NET Cor

2024-07-01 00:00:06

ASP.NET開源

2021-03-04 11:10:29

容器化Docker虛擬機(jī)

2019-08-12 08:00:00

ASP.NetASP.Net Cor編程語言

2021-01-11 05:20:05

Controller代碼數(shù)據(jù)層

2024-07-02 08:45:08

2009-07-31 09:00:44

ASP.NET生成隨機(jī)

2021-01-15 05:38:28

ASPHttp端口

2009-08-04 13:38:36

ASP.NET用戶控件

2024-09-24 17:34:05

2021-01-05 07:51:06

版本化ASP

2021-01-31 22:56:50

FromServiceASP

2021-02-03 13:35:25

ASPweb程序

2021-03-03 22:37:16

MediatR中介者模式

2021-03-10 09:40:43

LamarASP容器

2021-02-28 20:56:37

NCache緩存框架

2021-01-28 22:39:35

LoggerMessa開源框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)