Share via


Overzicht van versleuteling, digitale handtekeningen en hash-algoritmen in .NET

Dit artikel bevat een overzicht van de versleutelingsmethoden en -procedures die worden ondersteund door .NET, met inbegrip van de ClickOnce-manifesten.

Inleiding tot cryptografie

Openbare netwerken zoals internet bieden geen middel voor veilige communicatie tussen entiteiten. Communicatie via dergelijke netwerken is vatbaar voor lees- of zelfs wijziging door onbevoegde derden. Cryptografie helpt gegevens te beschermen tegen weergave, biedt manieren om te detecteren of gegevens zijn gewijzigd en helpt een veilig communicatiemiddel te bieden via anders onveilige kanalen. Gegevens kunnen bijvoorbeeld worden versleuteld met behulp van een cryptografisch algoritme, verzonden in een versleutelde status en later ontsleuteld door de beoogde partij. Als een derde partij de versleutelde gegevens onderschept, is het lastig om te ontcijferen.

In .NET beheren de klassen in de System.Security.Cryptography naamruimte veel details van cryptografie voor u. Sommige zijn wrappers voor implementaties van besturingssystemen, terwijl andere uitsluitend beheerde implementaties zijn. U hoeft geen expert in cryptografie te zijn om deze klassen te gebruiken. Wanneer u een nieuw exemplaar van een van de versleutelingsalgoritmeklassen maakt, worden sleutels automatisch gegenereerd voor gebruiksgemak en zijn standaardeigenschappen zo veilig en veilig mogelijk.

Cryptografische primitieven

In een typische situatie waarin cryptografie wordt gebruikt, communiceren twee partijen (Alice en Bob) via een niet-beveiligd kanaal. Alice en Bob willen ervoor zorgen dat hun communicatie onbegrijpelijk blijft voor iedereen die misschien luistert. Bovendien moet Alice, omdat Alice en Bob zich op externe locaties bevinden, ervoor zorgen dat de informatie die ze ontvangt van Bob niet door iemand is gewijzigd tijdens de verzending. Daarnaast moet ze ervoor zorgen dat de informatie echt afkomstig is van Bob en niet van iemand die Bob nabootst.

Cryptografie wordt gebruikt om de volgende doelen te bereiken:

  • Vertrouwelijkheid: om de identiteit of gegevens van een gebruiker te beschermen tegen lezen.

  • Gegevensintegriteit: om te voorkomen dat gegevens worden gewijzigd.

  • Verificatie: Om ervoor te zorgen dat gegevens afkomstig zijn van een bepaalde partij.

  • Niet-weerlegbaarheid: om te voorkomen dat een bepaalde partij weigert dat ze een bericht hebben verzonden.

Om deze doelen te bereiken, kunt u een combinatie van algoritmen en procedures gebruiken die cryptografische primitieven worden genoemd om een cryptografisch schema te maken. De volgende tabel bevat de cryptografische primitieven en hun gebruik.

Cryptografische primitieve Gebruik
Versleuteling van geheime sleutels (symmetrische cryptografie) Voert een transformatie uit op gegevens om te voorkomen dat deze door derden worden gelezen. Dit type versleuteling maakt gebruik van één gedeelde, geheime sleutel voor het versleutelen en ontsleutelen van gegevens.
Versleuteling van openbare sleutels (asymmetrische cryptografie) Voert een transformatie uit op gegevens om te voorkomen dat deze door derden worden gelezen. Dit type versleuteling maakt gebruik van een openbaar/persoonlijk sleutelpaar voor het versleutelen en ontsleutelen van gegevens.
Cryptografische ondertekening Hiermee kunt u controleren of gegevens afkomstig zijn van een specifieke partij door een digitale handtekening te maken die uniek is voor die partij. Dit proces maakt ook gebruik van hash-functies.
Cryptografische hashes Kaarten gegevens van elke lengte tot een bytereeks met vaste lengte. Hashes zijn statistisch uniek; een andere reeks van twee bytes zal niet hashen naar dezelfde waarde.

Versleuteling van geheime sleutels

Met versleutelingsalgoritmen voor geheimsleutels wordt één geheime sleutel gebruikt voor het versleutelen en ontsleutelen van gegevens. U moet de sleutel beveiligen tegen toegang door onbevoegde agenten, omdat elke partij met de sleutel deze kan gebruiken om uw gegevens te ontsleutelen of hun eigen gegevens te versleutelen, waarbij wordt geclaimd dat deze afkomstig is van u.

Versleuteling van geheime sleutels wordt ook wel symmetrische versleuteling genoemd, omdat dezelfde sleutel wordt gebruikt voor versleuteling en ontsleuteling. Versleutelingsalgoritmen voor geheime sleutels zijn zeer snel (vergeleken met algoritmen voor openbare sleutels) en zijn zeer geschikt voor het uitvoeren van cryptografische transformaties op grote gegevensstromen. Asymmetrische versleutelingsalgoritmen zoals RSA zijn wiskundig beperkt in de hoeveelheid gegevens die ze kunnen versleutelen. Symmetrische versleutelingsalgoritmen hebben over het algemeen deze problemen niet.

Een type geheimsleutel-algoritme dat een blokversleuteling wordt genoemd, wordt gebruikt om één gegevensblok tegelijk te versleutelen. Versleutelingsblokken zoals Data Encryption Standard (DES), TripleDES en Advanced Encryption Standard (AES) transformeren een invoerblok van n bytes naar een uitvoerblok van versleutelde bytes. Als u een reeks bytes wilt versleutelen of ontsleutelen, moet u dit per blok doen. Omdat n klein is (8 bytes voor DES en TripleDES; 16 bytes [de standaardinstelling], 24 bytes of 32 bytes voor AES), moeten gegevenswaarden die groter zijn dan n één blok tegelijk worden versleuteld. Gegevenswaarden die kleiner zijn dan n moeten worden uitgebreid naar n om te kunnen worden verwerkt.

Een eenvoudige vorm van blokcodering wordt de elektronische codeboekmodus (ECB) genoemd. DE ECB-modus wordt niet als veilig beschouwd, omdat deze geen initialisatievector gebruikt om het eerste blok zonder opmaak te initialiseren. Voor een bepaalde geheime sleutel k versleutelt een eenvoudige blokversleuteling die geen initialisatievector gebruikt hetzelfde invoerblok met tekst zonder opmaak in hetzelfde uitvoerblok van coderingstekst. Als u dus dubbele blokken in de invoerstroom zonder tekst hebt, hebt u dubbele blokken in de uitvoercodetekststroom. Deze dubbele uitvoerblokken waarschuwen onbevoegde gebruikers voor de zwakke versleuteling die de algoritmen gebruikt die mogelijk zijn gebruikt en de mogelijke aanvalsmodi. De ECB-coderingsmodus is daarom vrij kwetsbaar voor analyse en uiteindelijk sleuteldetectie.

De blokcoderingsklassen die zijn opgegeven in de basisklassebibliotheek gebruiken een standaardketenmodus met de naam CBC (Cipher-Block Chaining), hoewel u deze standaardinstelling desgewenst kunt wijzigen.

CBC-coderingen overwinnen de problemen met betrekking tot ECB-coderingen met behulp van een initialisatievector (IV) om het eerste blok zonder tekst te versleutelen. Elk volgend blok zonder opmaak ondergaat een bitwise exclusieve OR-bewerkingXOR () met het vorige coderingstekstblok voordat deze wordt versleuteld. Elk coderingstekstblok is daarom afhankelijk van alle vorige blokken. Wanneer dit systeem wordt gebruikt, kunnen veelvoorkomende berichtkoppen die mogelijk bekend zijn bij een niet-geautoriseerde gebruiker, niet worden gebruikt om een sleutel reverse-engineeren.

Een manier om gegevens in gevaar te brengen die zijn versleuteld met een CBC-codering, is door een volledige zoekopdracht van elke mogelijke sleutel uit te voeren. Afhankelijk van de grootte van de sleutel die wordt gebruikt om versleuteling uit te voeren, is dit soort zoekopdrachten zeer tijdrovend met zelfs de snelste computers en is daarom onbeerbaar. Grotere sleutelgrootten zijn moeilijker te ontcijferen. Hoewel versleuteling het theoretisch niet onmogelijk maakt voor een kwaadwillende persoon om de versleutelde gegevens op te halen, worden de kosten hiervoor wel hoger. Als het drie maanden duurt om een volledige zoekopdracht uit te voeren om gegevens op te halen die slechts een paar dagen zinvol zijn, is de volledige zoekmethode onpraktisch.

Het nadeel van geheime-sleutelversleuteling is dat twee partijen het eens zijn over een sleutel en IV en hun waarden hebben gecommuniceerd. De IV wordt niet beschouwd als een geheim en kan worden verzonden in tekst zonder opmaak met het bericht. De sleutel moet echter geheim worden gehouden van onbevoegde gebruikers. Vanwege deze problemen wordt versleuteling van geheime sleutels vaak samen met openbare-sleutelversleuteling gebruikt om de waarden van de sleutel en IV privé te communiceren.

Ervan uitgaande dat Alice en Bob twee partijen zijn die willen communiceren via een niet-beveiligd kanaal, kunnen ze geheime-sleutelversleuteling als volgt gebruiken: Alice en Bob gaan akkoord met het gebruik van één bepaald algoritme (bijvoorbeeld AES) met een bepaalde sleutel en IV. Alice stelt een bericht op en maakt een netwerkstroom (mogelijk een pijp- of netwerk-e-mail) waarop het bericht moet worden verzonden. Vervolgens versleutelt ze de tekst met behulp van de sleutel en IV en stuurt ze het versleutelde bericht en IV naar Bob via het intranet. Bob ontvangt de versleutelde tekst en ontsleutelt deze met behulp van de IV en eerder overeengekomen sleutel. Als de overdracht wordt onderschept, kan de interceptor het oorspronkelijke bericht niet herstellen, omdat ze de sleutel niet kennen. In dit scenario moet alleen de sleutel geheim blijven. In een praktijkscenario genereert Alice of Bob een geheime sleutel en maakt gebruik van openbare-sleutelversleuteling (asymmetrische) versleuteling om de geheime sleutel (symmetrisch) over te dragen aan de andere partij. Zie de volgende sectie voor meer informatie over versleuteling van openbare sleutels.

.NET biedt de volgende klassen waarmee versleutelingsalgoritmen voor geheime sleutels worden geïmplementeerd:

  • Aes

  • HMACSHA256, HMACSHA384 en HMACSHA512. (Dit zijn technisch geheimsleutelalgoritmen omdat ze berichtverificatiecodes vertegenwoordigen die worden berekend met behulp van een cryptografische hash-functie in combinatie met een geheime sleutel. Zie Hash-waarden verderop in dit artikel.)

Versleuteling van openbare sleutels

Versleuteling van openbare sleutels maakt gebruik van een persoonlijke sleutel die geheim moet worden gehouden van onbevoegde gebruikers en een openbare sleutel die openbaar kan worden gemaakt voor iedereen. De openbare sleutel en de persoonlijke sleutel zijn wiskundig gekoppeld; gegevens die zijn versleuteld met de openbare sleutel, kunnen alleen worden ontsleuteld met de persoonlijke sleutel en gegevens die zijn ondertekend met de persoonlijke sleutel, kunnen alleen worden geverifieerd met de openbare sleutel. De openbare sleutel kan voor iedereen beschikbaar worden gesteld; het wordt gebruikt voor het versleutelen van gegevens die naar de keeper van de persoonlijke sleutel worden verzonden. Cryptografische algoritmen met een openbare sleutel worden ook wel asymmetrische algoritmen genoemd, omdat één sleutel is vereist voor het versleutelen van gegevens en een andere sleutel is vereist voor het ontsleutelen van gegevens. Een eenvoudige cryptografische regel verbiedt hergebruik van sleutels en beide sleutels moeten uniek zijn voor elke communicatiesessie. In de praktijk zijn asymmetrische sleutels echter over het algemeen lang.

Twee partijen (Alice en Bob) kunnen als volgt openbare-sleutelversleuteling gebruiken: Eerst genereert Alice een openbaar/persoonlijk sleutelpaar. Als Bob Alice een versleuteld bericht wil sturen, vraagt hij haar om haar openbare sleutel. Alice stuurt Bob haar openbare sleutel via een onbeveiligd netwerk en Bob gebruikt deze sleutel om een bericht te versleutelen. Bob stuurt het versleutelde bericht naar Alice en ze ontsleutelt het met behulp van haar persoonlijke sleutel. Als Bob de sleutel van Alice heeft ontvangen via een onbeveiligd kanaal, zoals een openbaar netwerk, is Bob open voor een man-in-the-middle-aanval. Daarom moet Bob met Alice controleren of hij een juiste kopie van haar openbare sleutel heeft.

Tijdens de overdracht van de openbare sleutel van Alice kan een niet-geautoriseerde agent de sleutel onderscheppen. Bovendien kan dezelfde agent het versleutelde bericht van Bob onderscheppen. De agent kan het bericht echter niet ontsleutelen met de openbare sleutel. Het bericht kan alleen worden ontsleuteld met de persoonlijke sleutel van Alice, die niet is verzonden. Alice gebruikt haar persoonlijke sleutel niet om een antwoordbericht naar Bob te versleutelen, omdat iedereen met de openbare sleutel het bericht kan ontsleutelen. Als Alice een bericht naar Bob wil sturen, vraagt ze Bob om zijn openbare sleutel en versleutelt ze haar bericht met die openbare sleutel. Bob ontsleutelt het bericht vervolgens met behulp van zijn bijbehorende persoonlijke sleutel.

In dit scenario gebruiken Alice en Bob openbare-sleutelversleuteling (asymmetrische) versleuteling om een geheime sleutel (symmetrisch) over te dragen en geheime-sleutelversleuteling te gebruiken voor de rest van hun sessie.

De volgende lijst bevat vergelijkingen tussen cryptografische algoritmen voor openbare sleutels en geheime sleutels:

  • Cryptografische algoritmen voor openbare sleutels gebruiken een vaste buffergrootte, terwijl cryptografische algoritmen voor geheime sleutels een buffer met variabele lengte gebruiken.

  • Openbare-sleutelalgoritmen kunnen niet worden gebruikt om gegevens aan elkaar te koppelen in streams zoals geheime-sleutelalgoritmen dat kunnen, omdat alleen kleine hoeveelheden gegevens kunnen worden versleuteld. Daarom gebruiken asymmetrische bewerkingen niet hetzelfde streamingmodel als symmetrische bewerkingen.

  • Versleuteling van openbare sleutels heeft een veel grotere keyspace (bereik van mogelijke waarden voor de sleutel) dan versleuteling van geheime sleutels. Daarom is versleuteling van openbare sleutels minder gevoelig voor uitgebreide aanvallen die elke mogelijke sleutel proberen.

  • Openbare sleutels zijn eenvoudig te distribueren omdat ze niet hoeven te worden beveiligd, mits er een manier bestaat om de identiteit van de afzender te verifiëren.

  • Sommige openbare-sleutelalgoritmen (zoals RSA en DSA, maar niet Diffie-Hellman) kunnen worden gebruikt om digitale handtekeningen te maken om de identiteit van de afzender van gegevens te verifiëren.

  • Openbare-sleutelalgoritmen zijn erg traag vergeleken met geheime-sleutelalgoritmen en zijn niet ontworpen om grote hoeveelheden gegevens te versleutelen. Openbare-sleutelalgoritmen zijn alleen nuttig voor het overdragen van zeer kleine hoeveelheden gegevens. Normaal gesproken wordt versleuteling van openbare sleutels gebruikt om een sleutel en IV te versleutelen voor gebruik door een algoritme voor geheime sleutels. Nadat de sleutel en IV zijn overgedragen, wordt versleuteling van geheime sleutels gebruikt voor de rest van de sessie.

.NET biedt de volgende klassen die openbare-sleutelalgoritmen implementeren:

RSA staat zowel versleuteling als ondertekening toe, maar DSA kan alleen worden gebruikt voor ondertekening. DSA is niet zo veilig als RSA en we raden RSA aan. Diffie-Hellman kan alleen worden gebruikt voor het genereren van sleutels. Over het algemeen zijn openbare-sleutelalgoritmen beperkter in hun gebruik dan algoritmen met een persoonlijke sleutel.

Digitale handtekeningen

Openbare-sleutelalgoritmen kunnen ook worden gebruikt om digitale handtekeningen te vormen. Digitale handtekeningen verifiëren de identiteit van een afzender (als u de openbare sleutel van de afzender vertrouwt) en helpen de integriteit van gegevens te beschermen. Met behulp van een openbare sleutel die is gegenereerd door Alice, kan de ontvanger van de gegevens van Alice controleren of Alice deze heeft verzonden door de digitale handtekening te vergelijken met de gegevens van Alice en de openbare sleutel van Alice.

Als u cryptografie met openbare sleutels wilt gebruiken om een bericht digitaal te ondertekenen, past Alice eerst een hash-algoritme toe op het bericht om een berichtsamenvating te maken. De berichtsamenvating is een compacte en unieke weergave van gegevens. Alice versleutelt vervolgens de berichtsamenvating met haar persoonlijke sleutel om haar persoonlijke handtekening te maken. Na ontvangst van het bericht en de handtekening ontsleutelt Bob de handtekening met behulp van de openbare sleutel van Alice om de berichtsamenvating te herstellen en het bericht te hashes met hetzelfde hash-algoritme dat Alice heeft gebruikt. Als de berichtsamenvating die Bob precies overeenkomt met de berichtsamenvating die is ontvangen van Alice, weet Bob zeker dat het bericht afkomstig is van de eigenaar van de persoonlijke sleutel en dat de gegevens niet zijn gewijzigd. Als Bob vertrouwt dat Alice de eigenaar van de persoonlijke sleutel is, weet hij dat het bericht afkomstig is van Alice.

Notitie

Een handtekening kan door iedereen worden geverifieerd omdat de openbare sleutel van de afzender algemene kennis is en meestal is opgenomen in de digitale handtekeningindeling. Deze methode behoudt het geheim van het bericht niet; om het bericht geheim te maken, moet het ook worden versleuteld.

.NET biedt de volgende klassen die digitale handtekeningalgoritmen implementeren:

Hash-waarden

Hash-algoritmen wijzen binaire waarden van een willekeurige lengte toe aan kleinere binaire waarden van een vaste lengte, ook wel hash-waarden genoemd. Een hashwaarde is een numerieke weergave van een stukje gegevens. Als u een alinea met tekst zonder opmaak hasht en zelfs één letter van de alinea wijzigt, produceert een volgende hash een andere waarde. Als de hash cryptografisch sterk is, verandert de waarde aanzienlijk. Als bijvoorbeeld één bit van een bericht wordt gewijzigd, kan een sterke hash-functie een uitvoer produceren die verschilt met 50 procent. Veel invoerwaarden kunnen hashen naar dezelfde uitvoerwaarde. Het is echter rekenkundig onfeilbaar om twee afzonderlijke invoer te vinden die hash naar dezelfde waarde heeft.

Twee partijen (Alice en Bob) kunnen een hash-functie gebruiken om de integriteit van berichten te waarborgen. Ze selecteren een hash-algoritme om hun berichten te ondertekenen. Alice schrijft een bericht en maakt vervolgens een hash van dat bericht met behulp van het geselecteerde algoritme. Ze volgen vervolgens een van de volgende methoden:

  • Alice verzendt het bericht zonder opmaak en het gehashte bericht (digitale handtekening) naar Bob. Bob ontvangt en hashest het bericht en vergelijkt zijn hash-waarde met de hash-waarde die hij van Alice heeft ontvangen. Als de hashwaarden identiek zijn, is het bericht niet gewijzigd. Als de waarden niet identiek zijn, is het bericht gewijzigd nadat Alice het heeft geschreven.

    Helaas wordt met deze methode niet de echtheid van de afzender vastgesteld. Iedereen kan Alice imiteren en een bericht verzenden naar Bob. Ze kunnen hetzelfde hash-algoritme gebruiken om hun bericht te ondertekenen en alle Bob kan bepalen of het bericht overeenkomt met de handtekening. Dit is een vorm van een man-in-the-middle aanval. Zie Het voorbeeld van secure communication (Cryptography Next Generation) (CNG) voor meer informatie.

  • Alice verzendt het bericht zonder opmaak naar Bob via een niet-beveiligd openbaar kanaal. Ze stuurt het gehashte bericht naar Bob via een beveiligd privékanaal. Bob ontvangt het bericht zonder opmaak, hashes en vergelijkt de hash met de privé-uitgewisselde hash. Als de hashes overeenkomen, weet Bob twee dingen:

    • Het bericht is niet gewijzigd.

    • De afzender van het bericht (Alice) is authentiek.

    Om dit systeem te laten werken, moet Alice haar oorspronkelijke hash-waarde verbergen voor alle partijen behalve Bob.

  • Alice verzendt het bericht zonder opmaak naar Bob via een niet-beveiligd openbaar kanaal en plaatst het gehashte bericht op haar openbaar te bekijken website.

    Met deze methode voorkomt u dat berichten worden geknoeid door te voorkomen dat iemand de hash-waarde wijzigt. Hoewel het bericht en de hash door iedereen kunnen worden gelezen, kan de hash-waarde alleen door Alice worden gewijzigd. Een aanvaller die Alice wil imiteren, heeft toegang nodig tot de website van Alice.

Geen van de vorige methoden voorkomt dat iemand de berichten van Alice leest, omdat deze in tekst zonder opmaak worden verzonden. Voor volledige beveiliging zijn doorgaans digitale handtekeningen (berichtondertekening) en versleuteling vereist.

.NET biedt de volgende klassen voor het implementeren van hash-algoritmen:

.NET biedt MD5 en SHA1. Maar de MD5- en SHA-1-algoritmen zijn onveilig gebleken en SHA-2 wordt nu aanbevolen. SHA-2 bevat SHA256, SHA384 en SHA512.

Genereren van willekeurige getallen

Het genereren van willekeurige getallen is integraal voor veel cryptografische bewerkingen. Cryptografische sleutels moeten bijvoorbeeld zo willekeurig mogelijk zijn, zodat ze niet kunnen worden gereproduceerd. Cryptografische generatoren voor willekeurige getallen moeten uitvoer genereren die rekenkundig niet haalbaar is om te voorspellen met een waarschijnlijkheid die beter is dan een helft. Daarom mag elke methode voor het voorspellen van de volgende uitvoerbit niet beter presteren dan willekeurig raden. De klassen in .NET gebruiken generatoren voor willekeurige getallen om cryptografische sleutels te genereren.

De RandomNumberGenerator klasse is een implementatie van een algoritme van een generator voor willekeurige getallen.

ClickOnce-manifesten

Met de volgende cryptografieklassen kunt u informatie verkrijgen en verifiëren over manifesthandtekeningen voor toepassingen die zijn geïmplementeerd met behulp van ClickOnce-technologie:

Daarnaast bieden de volgende klassen specifieke handtekeninginformatie:

CNG-klassen (Cryptography Next Generation)

De CNG-klassen (Cryptography Next Generation) bieden een beheerde wrapper rond de systeemeigen CNG-functies. (CNG is de vervanging voor CryptoAPI.) Deze klassen hebben 'Cng' als onderdeel van hun namen. Centraal in de CNG-wrapperklassen is de CngKey sleutelcontainerklasse, die de opslag en het gebruik van CNG-sleutels abstraheert. Met deze klasse kunt u een sleutelpaar of een openbare sleutel veilig opslaan en ernaar verwijzen met behulp van een eenvoudige tekenreeksnaam. De op elliptische curve gebaseerde ECDsaCng handtekeningklasse en de ECDiffieHellmanCng versleutelingsklasse kunnen objecten gebruiken CngKey .

De CngKey klasse wordt gebruikt voor verschillende extra bewerkingen, waaronder openen, maken, verwijderen en exporteren van sleutels. Het biedt ook toegang tot de onderliggende sleutelhandgreep die moet worden gebruikt bij het rechtstreeks aanroepen van systeemeigen functies.

.NET bevat ook verschillende ondersteunende CNG-klassen, zoals de volgende:

Zie ook