Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ett ASP.NET program lagrar vanligtvis konfigurationsinformation i en Web.config fil. En del av den här informationen är känslig och garanterar skydd. Som standard kommer den här filen inte att hanteras av en webbplatsbesökare, men en administratör eller hackare kan få åtkomst till webbserverns filsystem och visa innehållet i filen. I den här självstudien lär vi oss att ASP.NET 2.0 gör att vi kan skydda känslig information genom att kryptera delar av Web.config-filen.
Inledning
Konfigurationsinformation för ASP.NET program lagras ofta i en XML-fil med namnet Web.config
. Under dessa självstudier har vi uppdaterat Web.config
ett fåtal gånger. För exempel, när du skapade Northwind
Typed DataSet i den första guiden, lades information om anslutningssträngen automatiskt till Web.config
i avsnittet <connectionStrings>
. Senare i självstudien Huvudsidor och Webbplatsnavigering uppdaterade Web.config
vi manuellt och lade till ett <pages>
element som anger att alla ASP.NET sidor i vårt projekt ska använda DataWebControls
temat.
Eftersom Web.config
kan innehålla känsliga data, till exempel anslutningssträngar, är det viktigt att innehållet Web.config
i hålls säkert och dolt för obehöriga användare. Som standard hanteras alla HTTP-begäranden till en fil med .config
tillägget av ASP.NET-motorn, som returnerar meddelandet Den här typen av sida visas inte i bild 1. Det innebär att besökare inte kan visa Web.config
filens innehåll genom att bara ange http://www.YourServer.com/Web.config i webbläsarens adressfält.
Bild 1: Besök Web.config
via en webbläsare Returnerar en Den här typen av sida hanteras inte Meddelande (Klicka om du vill visa en bild i full storlek)
Men vad händer om en angripare kan hitta någon annan exploatering som gör att hon kan visa filens Web.config
innehåll? Vad kan en angripare göra med den här informationen och vilka åtgärder kan vidtas för att ytterligare skydda känslig information i Web.config
? Lyckligtvis innehåller de flesta avsnitt i Web.config
inte känslig information. Vilken skada kan en angripare utföra om de vet namnet på standardtemat som används av dina ASP.NET sidor?
Vissa Web.config
avsnitt innehåller dock känslig information som kan innehålla anslutningssträngar, användarnamn, lösenord, servernamn, krypteringsnycklar och så vidare. Den här informationen finns vanligtvis i följande Web.config
avsnitt:
<appSettings>
<connectionStrings>
<identity>
<sessionState>
I den här självstudien tittar vi på tekniker för att skydda sådan känslig konfigurationsinformation. Som vi ser innehåller .NET Framework version 2.0 ett skyddat konfigurationssystem som gör det enkelt att kryptera och dekryptera valda konfigurationsavsnitt programmatiskt.
Anmärkning
Den här självstudien avslutas med en titt på Microsofts rekommendationer för att ansluta till en databas från ett ASP.NET program. Förutom att kryptera anslutningssträngarna kan du hjälpa dig att förstärka systemet genom att se till att du ansluter till databasen på ett säkert sätt.
Steg 1: Utforska ASP.NET 2,0 s skyddade konfigurationsalternativ
ASP.NET 2.0 innehåller ett skyddat konfigurationssystem för kryptering och dekryptering av konfigurationsinformation. Detta inkluderar metoder i .NET Framework som kan användas för att programmatiskt kryptera eller dekryptera konfigurationsinformation. Det skyddade konfigurationssystemet använder providermodellen som gör att utvecklare kan välja vilken kryptografiiimplementering som ska användas.
.NET Framework levereras med två skyddade konfigurationsprovidrar:
-
RSAProtectedConfigurationProvider
– använder den asymmetriska RSA-algoritmen för kryptering och dekryptering. -
DPAPIProtectedConfigurationProvider
– använder Windows Data Protection API (DPAPI) för kryptering och dekryptering.
Eftersom det skyddade konfigurationssystemet implementerar leverantörsdesignmönstret är det möjligt att skapa en egen skyddad konfigurationsprovider och ansluta den till ditt program. Mer information om den här processen finns i Implementera en skyddad konfigurationsprovider .
RSA- och DPAPI-leverantörerna använder nycklar för sina krypterings- och dekrypteringsrutiner, och dessa nycklar kan lagras på dator- eller användarnivå. Nycklar på datornivå är idealiska för scenarier där webbprogrammet körs på en egen dedikerad server eller om det finns flera program på en server som behöver dela krypterad information. Nycklar på användarnivå är ett säkrare alternativ i delade värdmiljöer där andra program på samma server inte ska kunna dekryptera programmets skyddade konfigurationsavsnitt.
I den här handledningen kommer våra exempel att använda DPAPI-leverantören och maskinnivånycklar. Mer specifikt kommer vi att titta på kryptering av <connectionStrings>
avsnittet i Web.config
, även om det skyddade konfigurationssystemet kan användas för att kryptera de flesta avsnitt Web.config
. Information om hur du använder nycklar på användarnivå eller om hur du använder RSA-providern finns i resurserna i avsnittet Ytterligare läsningar i slutet av den här självstudien.
Anmärkning
Leverantörerna RSAProtectedConfigurationProvider
och DPAPIProtectedConfigurationProvider
registreras i machine.config
-filen med leverantörnamnen RsaProtectedConfigurationProvider
respektive DataProtectionConfigurationProvider
. När du krypterar eller dekrypterar konfigurationsinformation måste vi ange lämpligt providernamn (RsaProtectedConfigurationProvider
eller DataProtectionConfigurationProvider
) i stället för det faktiska typnamnet (RSAProtectedConfigurationProvider
och DPAPIProtectedConfigurationProvider
). Du hittar machine.config
filen i $WINDOWS$\Microsoft.NET\Framework\version\CONFIG
mappen .
Steg 2: Programmatiskt kryptera och dekryptera konfigurationsavsnitt
Med några rader kod kan vi kryptera eller dekryptera ett visst konfigurationsavsnitt med hjälp av en angiven provider. Koden, som vi snart kommer att se, behöver bara programmatiskt referera till lämpligt konfigurationsavsnitt, anropa dess ProtectSection
eller UnprotectSection
metod och sedan anropa Save
metoden för att spara ändringarna. Dessutom innehåller .NET Framework ett användbart kommandoradsverktyg som kan kryptera och dekryptera konfigurationsinformation. Vi kommer att utforska det här kommandoradsverktyget i steg 3.
För att illustrera programmatiskt skydd av konfigurationsinformation ska vi skapa en ASP.NET sida som innehåller knappar för kryptering och dekryptering av <connectionStrings>
avsnittet i Web.config
.
Börja med att öppna sidan EncryptingConfigSections.aspx
i AdvancedDAL
mappen. Dra en TextBox-kontroll från verktygslådan till designern och ange dess ID
egenskap till WebConfigContents
, dess TextMode
egenskap till MultiLine
och dess Width
egenskaper Rows
till 95% respektive 15. Den här TextBox-kontrollen visar innehållet Web.config
i så att vi snabbt kan se om innehållet är krypterat eller inte. I ett riktigt program skulle du naturligtvis aldrig vilja visa innehållet i Web.config
.
Under textrutan lägger du till två knappkontroller med namnet EncryptConnStrings
och DecryptConnStrings
. Ställ in deras textegenskaper till Kryptera anslutningssträngar och Dekryptera anslutningssträngar.
Nu bör skärmen se ut ungefär som i bild 2.
Bild 2: Lägg till en textruta och två knappwebbkontroller på sidan (Klicka om du vill visa en bild i full storlek)
Därefter måste vi skriva kod som läser in och visar innehållet Web.config
i i WebConfigContents
textrutan när sidan läses in först. Lägg till följande kod i sidans code-behind-klass. Den här koden lägger till en metod med namnet DisplayWebConfig
och anropar den Page_Load
från händelsehanteraren när Page.IsPostBack
är false
:
protected void Page_Load(object sender, EventArgs e)
{
// On the first page visit, call DisplayWebConfig method
if (!Page.IsPostBack)
DisplayWebConfig();
}
private void DisplayWebConfig()
{
// Reads in the contents of Web.config and displays them in the TextBox
StreamReader webConfigStream =
File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
string configContents = webConfigStream.ReadToEnd();
webConfigStream.Close();
WebConfigContents.Text = configContents;
}
Metoden DisplayWebConfig
använder File
klassen för att öppna programmets Web.config
fil, StreamReader
klassen för att läsa dess innehåll i en sträng och Path
klassen för att generera den fysiska sökvägen till Web.config
filen. De här tre klasserna finns alla i System.IO
namnområdet. Därför måste du lägga till en using
System.IO
-instruktion överst i code-behind-klassen eller alternativt prefixa dessa klasser med System.IO.
.
Sedan måste vi lägga till händelsehanterare för de två knappkontrollerna Click
och lägga till nödvändig kod för att kryptera och dekryptera <connectionStrings>
avsnittet med hjälp av en nyckel på datornivå med DPAPI-providern. Dubbelklicka på var och en av knapparna från designern för att lägga till en Click
händelsehanterare i klassen code-behind och lägg sedan till följande kod:
protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only encrypt the section if it is not already protected
if (!connectionStrings.SectionInformation.IsProtected)
{
// Encrypt the <connectionStrings> section using the
// DataProtectionConfigurationProvider provider
connectionStrings.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings =
config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only decrypt the section if it is protected
if (connectionStrings.SectionInformation.IsProtected)
{
// Decrypt the <connectionStrings> section
connectionStrings.SectionInformation.UnprotectSection();
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
Koden som används i de två händelsehanterarna är nästan identisk. Båda börjar med att hämta information om den aktuella programfilen Web.config
via WebConfigurationManager
metoden class sOpenWebConfiguration
. Den här metoden returnerar webbkonfigurationsfilen för den angivna virtuella sökvägen. Därefter nås filens Web.config
<connectionStrings>
-avsnitt via klassens Configuration
GetSection(sectionName)
metod, som returnerar ett ConfigurationSection
objekt.
Objektet ConfigurationSection
innehåller en SectionInformation
egenskap som innehåller ytterligare information och funktioner om konfigurationsavsnittet. Som koden ovan visar kan vi avgöra om konfigurationsavsnittet är krypterat genom att kontrollera SectionInformation
egenskapens IsProtected
egenskap. Dessutom kan avsnittet krypteras eller dekrypteras via SectionInformation
egenskapen s ProtectSection(provider)
och UnprotectSection
metoderna.
Metoden ProtectSection(provider)
accepterar som indata en sträng som anger namnet på den skyddade konfigurationsprovider som ska användas vid kryptering.
EncryptConnString
I Händelsehanteraren för Button skickar vi DataProtectionConfigurationProvider till ProtectSection(provider)
metoden så att DPAPI-providern används. Metoden UnprotectSection
kan fastställa vilken provider som användes för att kryptera konfigurationsavsnittet och kräver därför inga indataparametrar.
När du har anropat ProtectSection(provider)
metoden eller UnprotectSection
måste du anropa Configuration
objektmetodenSave
för att spara ändringarna. När konfigurationsinformationen har krypterats eller dekrypterats och ändringarna har sparats anropar DisplayWebConfig
vi för att läsa in det uppdaterade Web.config
innehållet i TextBox-kontrollen.
När du har angett koden ovan testar du den genom att gå till EncryptingConfigSections.aspx
sidan via en webbläsare. Du bör först se en sida som visar innehållet i Web.config
med avsnittet <connectionStrings>
som visas i oformaterad text (se bild 3).
Bild 3: Lägg till en textruta och två knappwebbkontroller på sidan (Klicka om du vill visa en bild i full storlek)
Klicka nu på knappen Kryptera anslutningssträngar. Om valideringen av begäran är aktiverad, och markeringen skickas tillbaka från WebConfigContents
, skapas ett HttpRequestValidationException
som visar meddelandet att ett potentiellt farligt Request.Form
-värde identifierades från klienten. Validering av begäranden, som är aktiverat som standard i ASP.NET 2.0, förbjuder återkrav som innehåller okodad HTML och är utformat för att förhindra skriptinmatningsattacker. Den här kontrollen kan inaktiveras på sid- eller programnivå. Om du vill inaktivera den för den här sidan anger du ValidateRequest
inställningen till false
i @Page
direktivet. Direktivet @Page
finns överst på sidans deklarativa markering.
<%@ Page ValidateRequest="False" ... %>
Mer information om validering av begäranden, dess syfte, hur du inaktiverar den på sid- och programnivå samt hur du kodar kodningsmarkering för HTML finns i Begärandeverifiering – Förhindra skriptattacker.
När du har inaktiverat verifieringen av begäran för sidan kan du försöka klicka på knappen Kryptera anslutningssträngar igen. Vid postback kommer konfigurationsfilen att öppnas och dess <connectionStrings>
-avsnitt att krypteras med hjälp av DPAPI-leverantören. Textrutan uppdateras sedan för att visa det nya Web.config
innehållet. Som bild 4 visar <connectionStrings>
krypteras informationen nu.
Bild 4: Om du klickar på knappen Kryptera anslutningssträngar krypteras <connectionString>
avsnittet (klicka om du vill visa en bild i full storlek)
Det krypterade <connectionStrings>
avsnittet som genereras på min dator följer, även om en del av innehållet i elementet <CipherData>
har tagits bort för korthet:
<connectionStrings
configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue></CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Anmärkning
Elementet <connectionStrings>
anger den provider som används för att utföra krypteringen (DataProtectionConfigurationProvider
). Den här informationen används av UnprotectSection
metoden när knappen Dekryptera anslutningssträngar klickas.
När informationen om anslutningssträngen nås från Web.config
– antingen genom kod som vi skriver, från en SqlDataSource-kontroll eller den automatiskt genererade koden från TableAdapters i våra Typed DataSets – dekrypteras den automatiskt. Kort och gott behöver vi inte lägga till någon extra kod eller logik för att dekryptera det krypterade <connectionString>
avsnittet. Du kan visa detta genom att gå till någon av de tidigare självstudierna just nu, till exempel självstudien Enkel visning från avsnittet Grundläggande rapportering (~/BasicReporting/SimpleDisplay.aspx
). Som bild 5 visar fungerar självstudien precis som vi förväntar oss, vilket indikerar att informationen om den krypterade anslutningssträngen dekrypteras automatiskt av sidan ASP.NET.
Bild 5: Dataåtkomstskiktet dekrypterar automatiskt informationen om anslutningssträngen (Klicka om du vill visa en bild i full storlek)
Om du vill återställa <connectionStrings>
avsnittet till dess oformaterade textrepresentation klickar du på knappen Dekryptera anslutningssträngar. Vid postback bör du se anslutningssträngarna i Web.config
i klartext. Nu bör skärmen se ut som den gjorde när du först besökte den här sidan (se i bild 3).
Steg 3: Kryptera konfigurationsavsnitt med hjälp av aspnet_regiis.exe
.NET Framework innehåller en mängd olika kommandoradsverktyg i $WINDOWS$\Microsoft.NET\Framework\version\
mappen. I självstudien Använda SQL Cache Dependencies tittade vi till exempel på att använda aspnet_regsql.exe
kommandoradsverktyget för att lägga till den infrastruktur som krävs för SQL-cacheberoenden. Ett annat användbart kommandoradsverktyg i den här mappen är ASP.NET IIS-registreringsverktyget (aspnet_regiis.exe
). Som namnet antyder används verktyget ASP.NET IIS-registrering främst för att registrera ett ASP.NET 2.0-program med Microsofts professionella webbserver IIS. Förutom dess IIS-relaterade funktioner kan verktyget ASP.NET IIS-registrering också användas för att kryptera eller dekryptera angivna konfigurationsavsnitt i Web.config
.
Följande instruktion visar den allmänna syntax som används för att kryptera ett konfigurationsavsnitt med aspnet_regiis.exe
kommandoradsverktyget:
aspnet_regiis.exe -pef section physical_directory -prov provider
avsnittet är konfigurationsavsnittet för att kryptera (t.ex. connectionStrings), physical_directory är den fullständiga fysiska sökvägen till webbprogrammets rotkatalog och providern är namnet på den skyddade konfigurationsprovidern som ska användas (till exempel DataProtectionConfigurationProvider ). Om webbprogrammet är registrerat i IIS kan du också ange den virtuella sökvägen i stället för den fysiska sökvägen med hjälp av följande syntax:
aspnet_regiis.exe -pe section -app virtual_directory -prov provider
I följande aspnet_regiis.exe
exempel krypteras <connectionStrings>
avsnittet med DPAPI-providern med en nyckel på datornivå:
aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_CS"
-prov "DataProtectionConfigurationProvider"
aspnet_regiis.exe
På samma sätt kan kommandoradsverktyget användas för att dekryptera konfigurationsavsnitt. I stället för att använda växeln -pef
använder du -pdf
(eller i stället för -pe
, använder -pd
). Observera också att providernamnet inte är nödvändigt vid dekryptering.
aspnet_regiis.exe -pdf section physical_directory
-- or --
aspnet_regiis.exe -pd section -app virtual_directory
Anmärkning
Eftersom vi använder DPAPI-providern, som använder nycklar som är specifika för datorn, måste du köra aspnet_regiis.exe
från samma dator som webbsidorna hanteras från. Om du till exempel kör det här kommandoradsprogrammet från den lokala utvecklingsdatorn och sedan laddar upp den krypterade Web.config filen till produktionsservern, kommer produktionsservern inte att kunna dekryptera informationen om anslutningssträngen eftersom den krypterades med nycklar som är specifika för utvecklingsdatorn. RSA-providern har inte den här begränsningen eftersom det är möjligt att exportera RSA-nycklarna till en annan dator.
Förstå alternativ för databasautentisering
Innan något program kan utfärda SELECT
, INSERT
, UPDATE
eller DELETE
frågor till en Microsoft SQL Server-databas måste databasen först identifiera beställaren. Den här processen kallas autentisering och SQL Server tillhandahåller två autentiseringsmetoder:
-
Windows-autentisering – den process under vilken programmet körs används för att kommunicera med databasen. När du kör ett ASP.NET program via Visual Studio 2005 s ASP.NET Development Server förutsätter ASP.NET-programmet identiteten för den inloggade användaren. För ASP.NET program på Microsoft Internet Information Server (IIS) förutsätter ASP.NET program vanligtvis identiteten
domainName``\MachineName
ellerdomainName``\NETWORK SERVICE
, även om detta kan anpassas. - SQL-autentisering – ett användar-ID och lösenordsvärden anges som autentiseringsuppgifter för autentisering. Med SQL-autentisering anges användar-ID och lösenord i anslutningssträngen.
Windows-autentisering föredras framför SQL-autentisering eftersom det är säkrare. Med Windows-autentisering är anslutningssträngen fri från ett användarnamn och lösenord och om webbservern och databasservern finns på två olika datorer skickas inte autentiseringsuppgifterna via nätverket i klartext. Med SQL-autentisering hårdkodas dock autentiseringsuppgifterna i anslutningssträngen och överförs från webbservern till databasservern i klartext.
De här självstudierna har använt Windows-autentisering. Du kan se vilket autentiseringsläge som används genom att granska anslutningssträngen. Anslutningssträngen i Web.config
för våra självstudier har varit:
Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True
Integrerad säkerhet=True och utan användarnamn och lösenord anger att Windows-autentisering används. I vissa anslutningssträngar används termen Betrodd anslutning=Ja eller Integrerad säkerhet=SSPI i stället för Integrerad säkerhet=Sant, men alla tre anger användningen av Windows-autentisering.
I följande exempel visas en anslutningssträng som använder SQL-autentisering.
$CREDENTIAL_PLACEHOLDER$
är en platshållare för nyckel/värde-paret för lösenord. Observera att autentiseringsuppgifterna är inbäddade i anslutningssträngen:
Server=serverName; Database=Northwind; uid=userID; $CREDENTIAL_PLACEHOLDER$
Anta att en angripare kan visa programmets Web.config
fil. Om du använder SQL-autentisering för att ansluta till en databas som är tillgänglig via Internet kan angriparen använda den här anslutningssträngen för att ansluta till databasen via SQL Management Studio eller från ASP.NET sidor på sin egen webbplats. För att minimera det här hotet krypterar du informationen om anslutningssträngen i Web.config
med hjälp av det skyddade konfigurationssystemet.
Anmärkning
Mer information om de olika typerna av autentisering som är tillgängliga i SQL Server finns i Skapa säkra ASP.NET-program: Autentisering, auktorisering och säker kommunikation. Ytterligare anslutningssträngsexempel som illustrerar skillnaderna mellan Windows- och SQL-autentiseringssyntax finns i ConnectionStrings.com.
Sammanfattning
Som standard går det inte att komma åt filer med ett .config
tillägg i ett ASP.NET program via en webbläsare. Dessa typer av filer returneras inte eftersom de kan innehålla känslig information, till exempel databasanslutningssträngar, användarnamn och lösenord och så vidare. Det skyddade konfigurationssystemet i .NET 2.0 hjälper till att ytterligare skydda känslig information genom att tillåta att angivna konfigurationsavsnitt krypteras. Det finns två inbyggda skyddade konfigurationsprovidrar: en som använder RSA-algoritmen och en som använder Windows Data Protection API (DPAPI).
I den här självstudien tittade vi på hur du krypterar och dekrypterar konfigurationsinställningar med DPAPI-providern. Detta kan göras både programmatiskt, som vi såg i steg 2, samt via aspnet_regiis.exe
kommandoradsverktyget, som beskrivs i steg 3. Mer information om hur du använder nycklar på användarnivå eller om hur du använder RSA-providern i stället finns i resurserna i avsnittet Ytterligare läsning.
Lycka till med programmerandet!
Ytterligare läsning
Mer information om de ämnen som beskrivs i den här självstudien finns i följande resurser:
- Skapa ett säkert ASP.NET program: Autentisering, auktorisering och säker kommunikation
- Kryptera konfigurationsinformation i ASP.NET 2.0-program
-
Web.config
Kryptera värden i ASP.NET 2.0 - Anvisningar: Kryptera konfigurationsavsnitt i ASP.NET 2.0 med DPAPI
- Anvisningar: Kryptera konfigurationsavsnitt i ASP.NET 2.0 med hjälp av RSA
- Konfigurations-API:et i .NET 2.0
- Windows Data Protection
Om författaren
Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.
Särskilt tack till
Den här självstudieserien granskades av många användbara granskare. Huvudgranskare för den här handledningen var Teresa Murphy och Randy Schmidt. Vill du granska mina kommande MSDN-artiklar? Om så är fallet, hör av dig på mitchell@4GuysFromRolla.com.