Vous êtes sur la page 1sur 74

1

La scurit du .NET Framework

La scurit du .NET Framework


Sommaire
La scurit du .NET Framework ............................................................................................................ 1
1

Introduction..................................................................................................................................... 3

Gestion de la scurit de la CLR ...................................................................................................... 4


2.1

Prambule ............................................................................................................................... 4

2.2

Approfondissement de la scurit cot application ............................................................... 6

2.3

Paramtrage de la scurit de la CLR .................................................................................... 10

2.3.1

Les jeux d'autorisations ................................................................................................. 12

2.3.2

Les groupes de codes .................................................................................................... 16

2.3.3

Applications approuves ............................................................................................... 23

2.3.4

Le CAS et les permissions d'hte ................................................................................... 23

2.4
3

Gestion de la scurit du programme ........................................................................................... 24


3.1

Restrictions dexcution au niveau de lassembly................................................................. 24

3.2

Modification des droits au niveau dune classe/mthode .................................................... 30

3.3

Effectuer des demandes groupes ........................................................................................ 37

Scurisation des accs ................................................................................................................... 40


4.1

Authentification..................................................................................................................... 41

4.1.1

Authentification avec WindowsIdentity ........................................................................ 41

4.1.2

Cration d'une classe d'identit personnalise............................................................. 42

4.1.3

Authentification d'un groupe d'utilisateurs .................................................................. 42

4.1.4

Cration de classe d'identit de groupe personnalise ................................................ 45

4.1.5

Authentification gnrique ........................................................................................... 45

4.2
5

Configuration de scurit en ligne de commande ................................................................ 23

Autorisation ........................................................................................................................... 47

Gestion de la RBS Windows........................................................................................................... 49


5.1

Rappel sur le systme RBS Windows..................................................................................... 49

5.2

Gestion des droits via le code ............................................................................................... 51

La cryptographie dans le .NET ....................................................................................................... 54


6.1

Empreintes des donnes ....................................................................................................... 54

6.2

Chiffrement symtrique ........................................................................................................ 57

6.2.1

Outil annexe : La classe Rfc2898DeviveBytes................................................................ 57

6.2.2

Le chiffrement symtrique en pratique ........................................................................ 59


Date

La scurit du .NET Framework

6.3

6.3.1

RSACryptoServiceProvider ............................................................................................ 64

6.3.2

DSACryptoServiceProvider ............................................................................................ 69

6.4
7

Chiffrement asymtrique ...................................................................................................... 63

Signatures numriques.......................................................................................................... 70

Conclusion ..................................................................................................................................... 74

Date

La scurit du .NET Framework

1 Introduction
De nos jours, la scurit est un des piliers cl de toutes applications en entreprise. En effet, on
ne pourrait pas imaginer un monde dans lequel toutes les transactions bancaires lectroniques ne
soient pas effectues en utilisant des systmes de protections adapts.

Mme si avec les solutions actuelles, la scurit informatique absolue n'existe pas, il existe de
nombreux moyens permettant de donner du fil retordre aux hackers qui chercheraient exploiter
vos applications industrielles.
Dans ce chapitre, nous aborderons tout d'abord la scurit d'accs aux ressources locales
(propre la CLR). Ensuite, nous verrons comment grer les rgles de scurit d'accs aux ressources
puis nous terminerons le chapitre par les techniques de cryptographie implmentes par le .NET
Framework.

Date

La scurit du .NET Framework

2 Gestion de la scurit de la CLR


2.1 Prambule
Sur tous les systmes Windows, les personnes qui utilisent les machines sont reprsentes par
une entit virtuelle appele "utilisateur" (Et l'un des moyens permettant de lier les personnes aux
entits est l'utilisation d'un identifiant et d'un mot de passe). Ces utilisateurs peuvent soit avoir des
droits qui leur sont propre (comme par exemple, le droit d'excuter d'autre application, d'aller sur
internet, etc.) et/ou tre membre d'un "groupe d'utilisateur".
Ces groupes d'utilisateurs sont des entits qui attribuent des droits un ensemble
d'utilisateurs (Par exemple, l'utilisateur "Grant" et l'utilisateur "Dveloppeur" peuvent tous les deux
excuter des applications. Plutt que d'attribuer ce droit chaque utilisateur, nous utiliserons un
groupe d'utilisateur pouvant excuter des applications et nous feront en sorte que les deux
utilisateurs soient lis au groupe qui nous intresse).
Par dfaut, Windows est install avec une certaine liste de groupe dont chacun possde un
rle bien dfinit. Par exemple, sur une machine quipe de Windows Vista Business, nous avons les
groupes suivant (Vous pouvez accder la gestion simple des utilisateurs et groupes en passant par
"Panneau de configuration Outils d'administrationGestion de l'ordinateur". Vous pouvez
galement modifier le rle de chacun en choisissant "Stratgie de Scurit locale" au lieu de "Gestion
de l'ordinateur") :

Ce principe de groupes/utilisateurs ayant des rles particulier est appel "Role-based Security"
ou RBS.
Le Framework .NET possde un systme comparable afin de grer la scurit des applications
qui sont excutes via la CLR. Ce systme, en plus des possibilits via le code, est regroup sous le
nom de "Code Access Security" ou CAS en abrg. Les assemblies pourraient tre apparents aux
utilisateurs.
Note : Avant d'aller plus loin, il est impratif d'installer le .NET Framework 2.0 SDK disponible
ici. Ce SDK contient plusieurs outils de gestion du Framework .NET dont un composant enfichable de
la console MMC appel "Configuration du .NET Framework 2.0". Pour lancer l'utilitaire, cliquez le
Date

La scurit du .NET Framework

menu Windows, allez sur "Excuter" (ou directement dans la barre de recherche sous Vista) puis
tapez "mmc". L, faites "FichierAjouter/Supprimer un composant logiciel enfichable" et
slectionnez le composant ".NET Framework 2.0 Configuration".
Important : S'il est possible de grer totalement les possibilits des applications en code
manag, il est impossible d'effectuer les mme oprations sur du code non-manag (Cette notion de
code manag ou non sera vue dans les chapitre suivant). Vous devrez vous baser sur les rles
attribus chacun de vos utilisateurs/groupes pour viter les problmes. Aussi, mme si cela est
contraignant au dbut, n'oubliez jamais qu'une scurit digne de ce nom est celle qui accorde le
moins de privilges possibles aux utilisateurs. Ce principe est bien entendu vrai en ce qui concerne
les applications.

Date

La scurit du .NET Framework

2.2 Approfondissement de la scurit cot application


Si une personne peut saisir un identifiant et un mot de passe pour indiquer la machine quel
utilisateur lui attribuer, un programme ne peut pas se servir du mme procd.
Plutt que d'utiliser un identifiant et un code de scurit, les assemblies utiliseront des
"evidence" pour s'authentifier auprs de la CLR et c'est grce cette evidence que la CLR va savoir
dans quel groupe placer l'assembly qui demande tre excute.
Cette evidence peut contenir plusieurs proprits :
Application directory qui est le rpertoire dans lequel se trouve l'assembly.
Hash qui reprsente le code de hachage de l'assembly (en MD5 ou SHA1)
Publisher qui contient la signature numrique de l'diteur (n'est disponible que si
l'assembly a t signe numriquement)
Site, qui contient le site d'o a t tlcharg l'assembly.
Strong name, qui reprsente un nom cryptographique (l'assembly doit tre signe
galement pour avoir accs cette proprit)
URL qui est identique Site. La diffrence est que l'URL contient le nom de l'assembly
en plus du site.
Zone qui est la zone dans laquelle l'assembly s'excute.
Il existe deux types d'evidence :
Les evidence d'hte (Host evidence) qui contiennent des paramtres non modifiable.
Les evidence d'assembly (Assembly evidence) qui contiennent des paramtres
personnaliss
Cot code, vous pouvez accder ces informations en utilisant la proprit
AppDomain.CurrentDomain.Evidence. Dans l'exemple suivant, nous avons cr un nouveau

projet Winform dans lequel nous avons gliss une textbox configure en "Multiline = true",
"Scrollbars = Both" et "ReadOnly = true" (Optionnellement vous pouvez ajouter un couteur sur la
fentre principale l'vnement ResizeEnd) :
'VB
Public Sub New()
InitializeComponent()
Dim e As Evidence = AppDomain.CurrentDomain.Evidence
For Each o As Object In e
TextBox1.Text += o.ToString() + vbNewLine
Next
End Sub
Private Sub Partie_1_ResizeEnd(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.ResizeEnd
TextBox1.Size = New System.Drawing.Size(MyBase.Width - 50,
MyBase.Height - 50)
End Sub

Date

La scurit du .NET Framework

//C#
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Evidence e = AppDomain.CurrentDomain.Evidence;
foreach(Object o in e)
textBox1.Text += o.ToString() + "\n";
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
textBox1.Size = new System.Drawing.Size(base.Width - 50,
base.Height - 50);
}
}

Aprs compilation, vous devriez une fentre contenant le Hash de votre application, l'URL et sa
zone :

Date

La scurit du .NET Framework

Vous avez remarqu que certaines options ncessitent la signature de l'assembly. Pour signer
une assembly, cela reste relativement simple. Vous allez dans les proprits du projet et vous allez
sur l'onglet "Signature" et vous cochez la case "Signer l'assembly"

Ensuite, cliquez la liste droulante vide et slectionnez "<Nouveau>". L, vous saisissez le


nom que vous souhaitez donner votre fichier de signature ainsi qu'un ventuel mot de passe pour
protger le fichier en question (dans cet exemple, nous avons utilis le mot de passe "password") :

Si vous retournez dans votre solution, vous avez maintenant un fichier .pfx qui est apparu et
qui contient la signature numrique de votre application.
Notez que si vous r-excutez le projet prcdent, vous avez un champ supplmentaire
(StrongName) qui est apparu dans l'evidence utilise :

Date

La scurit du .NET Framework

Une autre information qui peut tre utile pour la suite, c'est de savoir rcuprer un jeton de
cl publique pour votre application. Pour cela, vous devez ouvrir la commande Visual Studio et saisir
la commande suivante :
sn -T "<chemin de votre assembly>"
En rponse directe, vous aurez le jeton de cl publique qui s'affichera dans la console (Pour
avoir un jeton disponible, il est obligatoire de signer votre application.) :
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
C:\Program Files\Microsoft Visual Studio 9.0\VC>sn -T "D:\Documents\dotNet Franc
e\Framework - VB\Chapitre 11\bin\Debug\Chapitre 11.exe"
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. Tous droits rservs.
Le jeton de la cl publique est 7a507855d0c56903
C:\Program Files\Microsoft Visual Studio 9.0\VC>

Date

10

La scurit du .NET Framework

2.3 Paramtrage de la scurit de la CLR


Dans cette partie, nous laissons un peu de ct les rgles de scurit au niveau application
pour nous intresser plus particulirement la configuration de la scurit de la CLR.
Pour commencer, nous allons ouvrir la console MMC et ajouter le composant enfichable ".NET
Framework 2.0 Configuration". Ensuite, vous dploierez successivement les lignes "Configuration du
Framework .NET 2.0" et "Poste de travail". Une fois cela fait, nous devrions avoir une fentre comme
a :

A ce stade, nous avons plusieurs lignes intressantes :


"Cache d'assemblys" qui permet d'ajouter/supprimer des assemblies rsidentes sur la
machine. Par dfaut, nous y retrouvons bien sur toutes les assemblies du .NET
Framework install mais galement d'autres assemblies ayant t installes par un
autre logiciel (notamment, les "Microsoft.VisualStudio" ou encore les
"Microsoft.Office").
"Services d'accs distant" qui va servir afficher la liste des paramtrages de scurit
en ce qui concerne l'accs distance.
"Stratgie de scurit du runtime" qui vous permettra de grer totalement les rgles
de scurit de la CLR.
"Applications" qui servira lister les assemblies configures et crer de nouvelles
rgles
Dans cette premire partie, nous nous intresserons plus particulirement la ligne "Stratgie
de scurit du runtime".
Si vous droulez cette ligne, vous avez trois autres champs disponibles :
Entreprise
Ordinateur
Utilisateur
Chacune de ces lignes reprsente en fait un niveau d'tendue des rgles de scurit qu'il
contient.
Date

11

La scurit du .NET Framework

La premire, Entreprise, concerne toute l'infrastructure dans laquelle se trouve la machine


configure ; c'est la partie la plus globale que l'on puisse trouver.
La seconde ligne, Ordinateur, permet de dfinir des rgles de scurit de la CLR qui
s'appliquent toute la machine et ce, peu importe l'utilisateur qui se servira des applications.
La dernire ligne, Utilisateur, est la plus restreinte au niveau tendue. Elle permet de dfinir
des rgles de scurit qui sont propre l'utilisateur authentifi sur la machine.

Pour cette partie, nous allons modifier les paramtres propres l'utilisateur en cours. En effet,
c'est la seule section qui contient toutes les catgories de scurit possible ; les autres ayant les
mmes fonctions mais plus grande chelle.
Si vous droulez la ligne Ordinateur, vous avez quatre nouvelles sections qui apparaissent :
"Groupes de codes", qui permettent d'associer des jeux d'autorisations avec des
assemblies particulires.
"Jeux d'autorisations", qui sont l'quivalent des groupes d'utilisateurs. Ils rassemblent
plusieurs rgles de scurit sous un mme nom.
"Assemblys de stratgie", qui contient toutes les assemblies soumises des rgles de
scurit et qui se trouvent dans le cache d'assembly (GAC pour Global Assembly
Cache).
"Applications approuves", qui contient toutes les assemblies qui sont considres comme digne de
confiance (Fully Trusted). Les autres assemblies soumises des rgles sont dites de confiance
partielle (Partially Trusted).

Date

12

La scurit du .NET Framework

2.3.1

Les jeux d'autorisations


Ces jeux d'autorisations vous permettent de rassembler une ou plusieurs rgle(s) de scurit
sous un mme nom. Si vous droulez cette ligne, vous pouvez remarquer que par dfaut, le
Framework propose sept jeux d'autorisations ; chacun d'entre eux ayant des autorisations bien
spcifiques ; les autorisations contenant leur tour un ensemble de permissions.
Note : Par dfaut, une page d'aide est affiche quand vous cliquez sur un jeu d'autorisation. Si
vous cliquez sur le lien "Afficher les autorisations", vous pouvez visualiser toutes les autorisations
que le jeu contient.

Pour voir plus en dtail chaque autorisation du jeu d'autorisation, il vous suffit de doublecliquer sur l'une des autorisations affiches pour en montrer les permissions. Ci-dessous, nous
affichons les permissions de l'autorisation nomme "Reflexion" :

Date

13

La scurit du .NET Framework

Vous pouvez bien sur crer vos propres jeux d'autorisation. Pour a, il vous suffit de faire clicdroit sur "Jeux d'autorisations" et de faire "Nouveau" :

Si vous avez export un jeu d'autorisation en XML, vous pouvez l'importer nouveau en
slectionnant "Importer un jeu d'autorisation partir d'un fichier XML". Sinon, laissez la premire
option slectionne, saisissez le nom et une description du jeu d'autorisations. Ensuite, cliquez sur
"Suivant".
Dans le cadre suivant, vous slectionnez les autorisations disponibles pour le jeu en cours
d'dition. Pour ajouter des autorisations, il vous suffit de cliquer sur l'autorisation ajouter et de
faire "Ajouter >>".

Date

14

La scurit du .NET Framework

Chaque autorisation porte un nom assez explicite qui n'a pas besoin d'tre dtaill. Aussi, je
me contenterais de dtailler ceux qui peuvent l'tre moins :
Magasin X509 : Spcifie l'autorisation d'accder, modifier, ajouter ou supprimer une
entre du magasin de certificats X509.
Service d'annuaire : Spcifie l'accs aux bases de donnes Active Directory.
DNS : Spcifie les autorisations effective quand l'envoi de requtes DNS.
Lorsque vous cliquez sur le bouton ajouter, une nouvelle fentre s'ouvre, dans laquelle vous
pouvez modifier les permissions :

Date

15

La scurit du .NET Framework

Dans cet exemple, nous avons ajout les permissions suivantes :


Accs en lecture sur le disque C: et en lecture/criture sur le disque D: (Fichier E/S)
Autorisation d'afficher les boites de dialogue pour ouvrir un fichier. (Boite de dialogue
Fichier)
Accs total aux interfaces utilisateurs. (Interface Utilisateur)
Accs total la gestion de la scurit de la CLR. (Scurit)
Vous pouvez bien sur modifier les permissions dj ajoutes en les slectionnant dans la
colonne de droite et en cliquant sur le bouton "Proprits".
Une fois que tout est termin, cliquez sur "Terminer" pour valider votre jeu d'autorisation. Il apparait
ensuite dans la liste des jeux d'autorisations disponible.

Date

16

La scurit du .NET Framework

2.3.2

Les groupes de codes

2.3.2.1 Configuration des groupes de codes


Les groupes de codes permettent donc de lier des assemblies un ou plusieurs jeux (x)
d'autorisations. Si vous droulez cette ligne, vous aurez toujours un groupe de code par dfaut
nomm "All_code" que vous ne pouvez pas supprimer. Ce groupe de code concerne toutes les
assemblies excutes et leur accorde le jeu d'autorisation "FullTrust" (Qui est quivalent placer les
assemblies dans la section "Applications approuves").
Dans le texte qui s'affiche quand All_code est slectionn, cliquez sur "modifier les proprits
du groupe de codes" :

Vous avez 3 onglets votre disposition :


Gnral, permettant de modifier la description ou le nom ainsi que deux autres
options du groupe de code.
Condition d'appartenance, qui fixe quel paramtre sera utilis pour dterminer quelles
assemblies seront affectes par ce groupe de code.
Jeu d'autorisation, qui permet de spcifier quel jeu d'autorisation sera utilis pour ce
groupe de code.
L aussi, vous pouvez crer vos propres groupes de codes. Il vous suffit de faire un clic droit sur
la ligne "All_code" et de faire "Nouveau". Comme prcdemment, vous pouvez saisir le nom et une
description ou importer un fichier XML. Une fois que vous avez cliqu sur Suivant, l'utilitaire va vous
demander de slectionner le paramtre qui sera recherch pour dfinir quelles assemblies seront
affectes par ce groupe de codes. Ci-dessous, nous avons slectionn le tri par nom fort du
programme et nous spcifions celui de notre assembly en utilisant le bouton "Importer" :

Date

17

La scurit du .NET Framework

Ensuite, cliquez sur "Suivant". Sur la fentre suivante, vous slectionnerez le jeu
d'autorisations qui rgira les permissions du groupe de code (Vous pouvez aussi choisir de crer un
nouveau jeu d'autorisations) :

Date

18

La scurit du .NET Framework

Dans l'exemple, nous basons notre groupe de codes sur le jeu d'autorisations cr plus haut.
Quand tout est paramtr selon vos besoins, cliquez sur "Suivant" puis sur "Terminer". De toute
faon, vous pourrez modifier les autorisations du groupe plus tard.
Pour l'exemple, nous modifierons le groupe de codes cr et nous cocherons la case "Ce
niveau de stratgie ne bnficiera que des autorisations du jeu d'autorisation associ ce groupe de
codes" ; la raison en sera explique plus bas.
Cot code, on rutilisera le projet cr au dbut de ce chapitre ; Nous n'enlverons aucun code
mais nous ajouterons le code suivant dans le constructeur de la classe principale, juste avant la
boucle foreach :
'VB
Try
Dim s As System.Windows.Forms.SaveFileDialog = New
System.Windows.Forms.SaveFileDialog()
s.ShowDialog()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
//C#
try
{
System.Windows.Forms.SaveFileDialog
System.Windows.Forms.SaveFileDialog();
s.ShowDialog();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

s = new

A l'excution du programme, vous devriez avoir un rsultat similaire celui-ci :

Date

19

La scurit du .NET Framework

Malgr notre ligne d'affichage d'une boite de dialogue SaveFileDialog, aucune autre fentre
que la fentre principale ne sera affich ; et c'est entirement explicable. Rappelez-vous, dans la
partie prcdente, notre jeu d'autorisations autorise l'affichage des fentres (Interface utilisateur)
mais interdit l'affichage des boites de dialogue en sauvegarde. Cette interdiction lve une exception
affiche dans la console.
Attention : La scurit du .NET Framework peut tre tout aussi puissante que le systme
RBS pour les utilisateurs de la machine Windows. Seulement, ce qui fait sa puissance peut
aussi rapidement devenir un vritable dsastre si elle est mal configure. Des rgles de
scurit trop exigeantes peuvent mme vous empcher de lancer Visual Studio ; ce
dernier utilisant certaines assemblies du Framework, il gnrera des erreurs tour de bras, vous
empchant ainsi toute utilisation normale.
Note : Pour vous aider configurer correctement vos rgles de scurit, n'hsitez pas utiliser
l'valuation d'assembly. A l'image de l'outil "Autorisation effective" pour les utilisateurs, il permet
d'afficher toutes les rgles de scurit affectant une assembly spcifie. Pour cela, faites clic-droit sur
"Stratgie de scurit du runtime" et slectionnez "Evaluer l'assembly".

Il ne vous reste plus qu' slectionner le fichier contenant l'assembly valuer, indiquer
quelles informations afficher et cliquer sur Suivant :

Date

20

La scurit du .NET Framework

Date

21

La scurit du .NET Framework

2.3.2.2 Notion de hirarchie des groupes


Dans l'exemple plus haut, je vous avais demand de cocher la case "Ce niveau de stratgie ne
bnficiera que des autorisations du jeu d'autorisation associ ce groupe de codes" sans
comprendre pourquoi. La raison est simple : les groupes de codes se basent sur un systme
hirarchisation des droits.
Dans un code orient objet, en gnral, quand une classe hrite d'une autre, la classe fille
dispose de tous les membres de la classe parente.
Les groupes de codes fonctionnent de la mme faon. Reprenons notre exemple :

Ici nous pouvons voir clairement que "Copie de GroupTest" est un groupe de code enfant du
groupe "All_code".
Tout l'heure, nous avions affich les autorisations effectives sur l'assembly et avions constat
que les rgles dfinies par notre jeu d'autorisation taient bien prsentes.
Maintenant, si nous modifions le groupe de code "Copie de GroupTest", que nous dcochons
la case indique et que nous affichons nouveau les autorisations effectives :

Date

22

La scurit du .NET Framework

Nous pouvons remarquer prsent que l'assembly est passe en "Non restreint".
Cette case "Ce niveau []" permet en fait de forcer la CLR appliquer uniquement les permissions du
jeu d'autorisation li au groupe de code et ce, sans tenir compte des autorisations du groupe de code
parent. Si nous la dcochons, notre groupe de code "Copie de GroupTest" va de nouveau hriter des
rgles de scurit du groupe "All_code" qui est configur pour permettre n'importe quel
programme de grer n'importe quelle ressource.

Date

23

La scurit du .NET Framework

2.3.3

Applications approuves
Cette section regroupe les applications "ClickOnce" ( dploiement rapide) considres
comme approuves, c'est-a-dire quelles sont rgies par des rgles de scurit non paramtrable.

2.3.4

Le CAS et les permissions d'hte


Quand vous configurez les rgles de scurit du .NET Framework, il faut bien garder en tte
qu'elles ne prvalent en rien sur les rgles de scurit tablies par l'OS qui sera charg d'excuter
votre assembly. Si, par exemple, le Framework est configur pour avoir un accs total au disque C:\
mais que l'utilisateur ne possde pas ces droits au niveau du systme d'exploitation, toute tentative
d'criture, de lecture ou d'excution sur C:\ chouera.

2.4 Configuration de scurit en ligne de commande


Pour les adeptes de la ligne de commande ou des scripts batch, il est tout fait possible de
configurer la scurit du Framework avec une invite de commande. Pour cela, il vous suffit d'utiliser
le
logiciel
"Caspol.exe"
qui
se
trouve
dans
le
dossier
"C:\Windows\Microsoft.NET\Framework\v2.0.50727". Si vous souhaitez avoir plus d'informations sur
l'utilisation de cet outil, je vous recommande ce lien qui explique tous les paramtres de cet
excutable.

Date

24

La scurit du .NET Framework

3 Gestion de la scurit du programme


Nous avons vu dans la premire partie beaucoup de thorie sur la scurit. A prsent, nous
allons voir comment faire en sorte que vos assemblies possdent strictement les droits dont elles ont
besoin afin de protger le systme sur lequel elles sont utilises.

3.1 Restrictions dexcution au niveau de lassembly


Pour cela nous allons indiquer explicitement, grce un ensemble de classes sous forme
dattributs et trois valeurs de lnumration SecurityAction, les permissions ncessaires au bon
fonctionnement de lapplication.
Grce cette mthode nous pouvons nous assurer que notre assembly nexcutera pas
certains bouts de codes sans en avoir la permission. Le Runtime va dabord vrifier que les demandes
de permissions minimum peuvent tre accordes et pourra renvoyer une exception si lune dentre
elle est refuse. Cela permet galement d'appliquer l'un des principes de base de la scurit, savoir
quil faut toujours donner une application ou un utilisateur seulement les droits ncessaires et
suffisants. Pour illustrer ce principe, on parle souvent de liste blanche et liste noire : Plutt que de
faire une liste des interdits sur une liste noire, il vaut mieux faire une liste des autorisations sur une
liste blanche.
Tout dabord nous allons voir en dtail les trois types de dclarations possibles. Celles-ci font
partie de lnumration SecurityAction et ne sappliquent qu lassembly. Dautres types de
dclarations sont disponibles dans SecurityAction mais ne sappliquent quaux classes et/ou
mthodes :
Valeur
Description
RequestMinimum
Associ une permission, permet dindiquer que les demandes d'accs
sont analyses avant l'excution du code. Si une demande de
permission est refuse, une exception est leve.
RequestOptional
Permet de crer une liste blanche des demandes de permissions. Ces
demandes seront analyses au moment de l'excution du code. A partir
du moment o une demande d'accs est dclare RequestOptional,
toutes les autres demandes qui ne sont pas faites explicitement seront
refuses et lveront des exceptions.
RequestRefuse
Permet de refuser explicitement une permission de manire crer une
liste noire. Une demande de permission refuse lve une exception.
Note : Le nom RequestOptional peut porter confusion. En effet il nindique pas une demande de
permission optionnelle mais est bien obligatoire pour autoriser des actions.
Dans chaque demande de permission, vous pouvez faire suivre votre paramtre SecurityAction
par dautres paramtres sous la forme dune proprit suivis dun gal et de sa valeur. Par exemple,
la plus courante Unrestricted permet dautoriser (true) ou non (false) laccs complet la
ressource.
Nous verrons deux autres proprits dans lexemple de code.
Dans tous les cas, il est important de surveiller les exceptions de type SecurityException grce
des blocs Try-Catch. Ainsi, si une demande de droit na pu aboutir, vous pourrez indiquer dans la
console ou le journal dvnements les permissions activer pour que lapplication fonctionne.

Date

25

La scurit du .NET Framework

Maintenant que nous avons vu les trois principales valeurs qui nous intressent dans
lnumration SecurityAction, nous allons dtailler les demandes de permissions principales
misent disposition par le Framework .NET :
Classes
Description
AspNetHostingPermission
Demande daccs entre le systme et un environnement
Asp.NET.
DataProtectionPermission
Demande daccs la mmoire et des donnes chiffres.
DirectoryServicesPermission
Demande
daccs

lespace
de
nom
System.DirectoryServices.
DnsPermission
Demande daccs un serveur DNS.
EnvironmentPermission
Demande daccs aux variables du systme et de
lenvironnement de lutilisateur.
EventLogPermission
Demande daccs au journal dvnements.
FileDialogPermission
Demande daccs un fichier du systme partir dune
boite de dialogue.
FileIOPermission
Demande daccs un fichier du systme.
IsolatedStorageFilePermission Demande daccs aux zones de stockages isoles
KeyContainerPermission
Demande daccs un conteneur de cl. Voir la partie sur
la scurit des donnes.
OdbcPermission
Demande daccs une source de donne ODBC.
OleDbPermission
Demande daccs une base de donnes en utilisant
OleDb.
OraclePermission
Demande daccs une base de donnes Oracle.
PerformanceCounterPermission
Demande daccs aux compteurs de performances.
PrintingPermission
Demande daccs aux imprimantes.
ReflectionPermissions
Demande de permission dutilisation des outils de lespace
de nom System.Reflection.
RegistryPermission
Demande daccs au registre Windows.
ServiceControllerPermission
Demande daccs au contrle des services.
SocketPermission
Demande lautorisation de crer une connexion par
sockets.
SqlClientPermission
Demande laccs une base de donnes SQL.
UIPermission
Demande daccs linterface utilisateur et au pressepapier. Ncessaire au dbuggeur de Visual Studio.
WebPermission
Demande daccs une ressource sur internet par HTTP.
Note : Ces classes possdent toutes une version attribut mais vous pouvez les utiliser en tant
quobjets. Nous ne dtaillerons pas cette faon de faire.

Date

26

La scurit du .NET Framework

Nous allons illustrer un peu ce que nous avons vu avec un court exemple :
Tout dabord nous crons un fichier texte la racine de notre disque C : que nous appelons
test.txt. Ensuite, nous relanons la console MMC et nous autorisons l'accs au fichier par notre
assembly uniquement en lecture (Par souci de simplicit, ajoutez galement l'accs total la gestion
de la scurit et l'interface utilisateur).

Ensuite nous allons accder dans notre application une premire fois en lecture et une
seconde en criture.

Date

27

La scurit du .NET Framework

'VB
Imports System.IO
Imports System.Security.Permissions
<Assembly: UIPermission(SecurityAction.RequestOptional,
Clipboard:=UIPermissionClipboard.AllClipboard,
Window:=UIPermissionWindow.AllWindows)> _
<Assembly: FileIOPermission(SecurityAction.RequestMinimum,
Read:="C:\test.txt")> _
<Assembly: FileIOPermission(SecurityAction.RequestOptional,
Write:="C:\test.txt")> _
Module partie2
Public Sub Main()
Try
Console.WriteLine("Tentative de lecture")
Dim sr As StreamReader = New StreamReader("c:\test.txt")
sr.Close()
Console.WriteLine("Tentative d'criture")
Dim sw As StreamWriter = New StreamWriter("c:\test.txt")
sw.Close()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub
End Module

Date

28

La scurit du .NET Framework

//C#
using System;
using System.IO;
using System.Security.Permissions;
[assembly: UIPermission(SecurityAction.RequestOptional, Window =
UIPermissionWindow.AllWindows, Clipboard =
UIPermissionClipboard.AllClipboard)]
[assembly: FileIOPermission(SecurityAction.RequestMinimum, Read =
@"C:\test.txt")]
[assembly: FileIOPermission(SecurityAction.RequestOptional, Write =
@"C:\test.txt")]
namespace Chapitre_11
{
class Partie2
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Tentative de lecture")
StreamReader sr = new StreamReader(@"c:\test.txt");
sr.Close();
Console.WriteLine("Tentative d'criture")
StreamWriter sw = new StreamWriter(@"c:\test.txt");
sw.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}

Nous utilisons ici quatre attributs :


UIPermission est en RequestOptional. Cela veut dire que dans toute l'assembly, les
demandes d'accs cette ressource seront testes aprs valuation du code. Cela veut
galement dire que dans toutes mon assembly, toute demande de permission non explicite
sera refuse. Nous lui avons assign deux proprits permettant dindiquer que nous
demandons laccs toutes les fentres et galement tous les presse-papiers. Cet attribut
est absolument ncessaire si vous excutez votre application en utilisant le dbuggeur Visual
Studio.
Le premier FileIOPermission nous permet de demander la permission daccder en
lecture au fichier test.txt. Cest une demande minimum, cela veut dire que si elle nest pas
accepte, une exception sera leve avant mme que la tentative d'accs au fichier soit
effectue.
Le second FileIOPermission nous permet de demander la permission daccder en
criture au fichier test.txt. Cest une demande optional c'est--dire que l'analyse des rgles
de scurit sera faite au moment o une demande d'accs en criture au fichier est
effectue. Si elle est refuse, une exception sera leve.

Date

29

La scurit du .NET Framework

Si nous lanons lapplication, voila lexception qui sera leve :


Tentative de lecture
Tentative d'criture
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPermission, mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Il en sera de mme si vous ne laissez que le premier FileIOPermission.
Lexception nous indique que nous navons pas laccs test.txt en criture ; La demande est
donc refuse.
En

revanche,

si

nous

changeons

le

second

paramtrage

FileIOPermission

de

RequestOptional RequestMinimum, il nous sera impossible de compiler le projet :

Pour finir, supprimez les rgles de scurit dfinie dans ce test grce la console MMC et
modifiez le second paramtrage FileIOPermission de RequestOptional RequestRefuse.
Tentative de lecture
Tentative d'criture
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPermission, mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Nous aurons droit la mme erreur que si nous avions laiss le paramtrage de la CLR avec
une demande RequestOptional.
Maintenant que nous savons comment restreindre les permissions au niveau de l'assembly,
nous pourrions galement nous demander comment faire pour appeler du code de confiance totale
partir d'une assembly de confiance partielle. Pour cela, rien de plus simple que d'ajouter l'attribut
suivant :
'VB
<Assembly: System.Security.AllowPartiallyTrustedCallers()>
//C#
[assembly: System.Security.AllowPartiallyTrustedCallers]

Sachez toutefois que les membres publiques d'une assembly non-signe sont accessibles
depuis l'extrieur, mme si cet attribut n'est pas prsent !

Date

30

La scurit du .NET Framework

3.2 Modification des droits au niveau dune classe/mthode


Nous avons vu prcdemment comment appliquer des mesures de scurit une assembly
par le code, nous allons maintenant voir comment les appliquer directement des classes ou des
mthodes.
Nous avions vu dans la partie prcdente lutilisation des attributs afin de crer des demandes
de permissions dclaratives en utilisant trois valeurs de lnumration SecurityAction. Au niveau
des mthodes et des classes, nous avons accs de nouvelles valeurs que voici :
Valeur
Description
Assert
Permet au code associ dtre excut par dautres portions de code se
trouvant aprs (dans la pile dappel) la partie quipe dune demande
de permission Assert et ce, mme sils nen font pas la demande. Bien
entendu la permission doit tre accorde dans lassembly contenant le
code. La permission autorise sera automatiquement restaure son
tat dorigine lorsque la pile dappel sera parcourue en sens inverse.
Demand
Fournit, la diffrence de Assert, une permission une seule portion de
code. Tous les autres codes se trouvant avant ou aprs dans la pile
dappel doivent galement faire une demande pour disposer des
mmes droits.
Deny
Permet de refuser explicitement un droit une portion de code. Tout
code se situant aprs dans la pile dappel aura galement une
interdiction de droit, sauf sil fait une demande de droits.
InheritanceDemand
Permet de sassurer que les classes qui hritent ou qui substituent une
mthode de la classe associe ont les autorisations ncessaires.
LinkDemand
Fourni une permission une portion de code ainsi qua tout code se
trouvant aprs dans la pile dappel. A la diffrence dAssert, la
permission ne sera restaure lors de la remonte de la pile dappel ce
qui peut reprsenter une importante faille de scurit.
PermitOnly
Supprime toute autorisation accorde jusquici et autorise uniquement
celle qui est affecte de PermitOnly.
Note : La notion de pile dappel est explique ici.
Comme ces notions sont un peu dlicates comprendre, nous allons essayer de les
comprendre en prenant un exemple de la vie courante. Imaginez que vous travaillez dans la S.A
Dotnet-France. Les locaux sont quips dune porte dentre quil faut scuriser afin de protger
laccs.
Nous avons plusieurs choix qui soffrent nous pour scuriser lentre. A chaque valeur de
lnumration prcdente, nous associons un dispositif particulier :
Assert peut tre compar un digicode. Ds quune personne entre le bon code, on lui
donne la possibilit de laisser entrer autant de personne quelle le souhaite ; Cependant,
nous obligerons la personne refermer la porte. Nous faisons alors confiance en la personne
qui a tap le code pour quelle ne soit accompagne que de personnes autorises. On gagne
ainsi du temps, mais en contrepartie, si un intrus se glisse dans le groupe nous nous
exposons un risque.
Demand peut tre associ un dispositif douverture par badge. Chaque employ doit ouvrir
lentre grce son badge, et nous savons ainsi qui rentre et quelle heure.
Deny et PermitOnly peuvent tre compar un vigile qui va dans le premier cas empcher
certaines personnes dentrer sur un critre en particulier, il va par exemple interdire lentre
tous ceux qui sont en Tee-shirt. Dans lautre cas, le vigile va seulement autoriser les
personnes correspondant certains critres, par exemple il laissera entrer seulement les
personnes en costume.

Date

31

La scurit du .NET Framework

Dans le cas de LinkDemand, nous avons choisit simplement de fermer la porte clef, ds
quune personne ouvert la porte, tous le monde peut entrer, tous le processus est simplifi,
mais les intrus peuvent rentrer trs facilement.
InheritanceDemand est une version plus pousse du dispositif douverture par badge. On
peut imaginer que nous avons rajouts un vigile qui va vrifier que les personnes qui
accompagnent un employ sont autorises entrer (par exemple des clients).
Maintenant que nous y voyons un peu plus clair sur la mthode dclarative de demande de
permissions, nous allons parler un petit peu de la mthode imprative.
Nous avons vu que pour faire une demande de permission dclarative, il nous fallait utiliser un
attribut au dessus de nos classes ou mthodes. Pour faire une demande de permission imprative,
nous allons instancier un objet qui hrite de CodeAccessPermission et utiliser les mthodes qui
conviennent. Cela va nous permettre de faire des demandes de permissions pour une partie prcise
dun bloc plutt que pour le bloc entier.
Les mthodes de CodeAccessPermission ne vous serons pas trangre puisquelles portent
le mme nom que les valeurs de lnumration SecurityAction et ont les mmes comportements.
En revanche LinkDemand et InheritanceDemand nexistent pas.
Afin de comprendre la diffrence entre les deux nous allons voir un exemple dutilisation des
deux mthodes. Notre exemple ne va utiliser que Demand, les autres actions seront vues ensuite.
VB
Imports System.IO
Imports System.Security.Permissions
<FileIOPermission(SecurityAction.Demand, Write:="C:\")> _
Public Sub Ecrire()
Dim sw As StreamWriter = New StreamWriter("C:\test.txt")
sw.WriteLine("blabla")
sw.Flush()
sw.Close()
End Sub
Public Sub EcrireDeux()
Dim FP As FileIOPermission = New
FileIOPermission(FileIOPermissionAccess.Write, "C:\test.txt")
FP.Demand()
Dim sw As StreamWriter = New StreamWriter("C:\test.txt")
sw.WriteLine("tructruc")
sw.Flush()
sw.Close()
End Sub
Public Sub Lire()
Dim sr As StreamReader = New StreamReader("C:\test.txt")
Console.WriteLine(sr.ReadToEnd())
sr.Close()
End Sub
Public Sub Main()
Ecrire()
Lire()
EcrireDeux()
Lire()
Console.Read()
End Sub

Date

32

La scurit du .NET Framework

//C#
using System.Security.Permissions;
using System.IO;
[FileIOPermission(SecurityAction.Demand, Write = @"C:\")]
public static void Ecrire()
{
StreamWriter sw = new StreamWriter(@"C:\test.txt");
sw.WriteLine("blabla");
sw.Flush();
sw.Close();
}
public static void EcrireDeux()
{
FileIOPermission FP = new
FileIOPermission(FileIOPermissionAccess.Write, @"C:\test.txt");
FP.Demand();
StreamWriter sw = new StreamWriter(@"C:\test.txt");
sw.WriteLine("tructruc");
sw.Flush();
sw.Close();
}
public static void Lire()
{
StreamReader sr = new StreamReader(@"C:\test.txt");
Console.WriteLine(sr.ReadToEnd());
sr.Close();
}
public static void Main(string[] args)
{
Ecrire();
Lire();
EcrireDeux();
Lire();
Console.Read();
}

Nous avons donc utilis la mthode dclarative pour la premire mthode Ecrire. Nous
demandons lautorisation dcrire sur tout le lecteur C, si la permission est accorde, nous pourrons
crire partout sur ce lecteur. Cependant, vous pouvez avoir les droits daccs au lecteur C sans pour
autant les avoir sur le fichier concern. Dans tous les cas, si vous ne possdez pas les droits
ncessaires, une exception sera leve.
Dans la deuxime mthode EcrireDeux, nous faisons une demande de permission
imprative. Nous indiquons que nous voulons crire sur le fichier test.txt en particulier. Grce cette
mthode nous allons pouvoir grer les cas o une demande est refuse afin quaucune exception ne
soit leve, nous allons le voir dans un exemple venir.
Bien entendu, les deux mthodes Ecrire et EcrireDeux ont le mme comportement final
comme en atteste la console :
blabla
tructruc
Nous allons reprendre notre exemple prcdent et grer le cas o la demande serait refuse.
Par exemple nous pourrons afficher une boite de dialogue demandant quel endroit lapplication
pourra enregistrer le fichier. Vous aurez besoin dimporter lespace de nom System.Security pour
effectuer la vrification :

Date

33

La scurit du .NET Framework

VB
Imports System.IO
Imports System.Security.Permissions
Imports System.Security
Public Sub EcrireDeux()
Dim FP As FileIOPermission = New
FileIOPermission(FileIOPermissionAccess.Write, "C:\test.txt")
If (SecurityManager.IsGranted(FP)) Then
Dim sw As StreamWriter = New StreamWriter("C:\test.txt")
sw.WriteLine("tructruc")
sw.Flush()
sw.Close()
Else
Console.WriteLine("Erreur")
End If
End Sub
//C#
using System.Security.Permissions;
using System.IO;
using System.Security;
public static void EcrireDeux()
{
FileIOPermission FP = new
FileIOPermission(FileIOPermissionAccess.Write, @"C:\test.txt");
if (SecurityManager.IsGranted(FP) == true)
{
StreamWriter sw = new StreamWriter(@"C:\test.txt");
sw.WriteLine("tructruc");
sw.Flush();
sw.Close();
}
else
{
Console.WriteLine("Erreur");
}
}

Nous avons un peu modifi notre mthode EcrireDeux, tout dabord, nous nutilisons plus
les mthodes de CodeAccessPermission. Nous instancions juste un objet FileIOPermission
qui sera vrifi dans la condition suivante. Nous vrifions que la permission est accorde grce la
mthode statique SecurityManager.IsGranted. Si la valeur retourne est true, alors cest que la
permission est accorde, nous pouvons crire dans notre fichier.
Bien entendu, sil est possible de faire des demandes de permissions, il est galement possible
de les interdire. Pour cela, vous pouvez procder galement de faon imprative ou dclarative.
Pour refuser des droits explicitement, vous pouvez utiliser :
Deny : Cette valeur va nous permettre de supprimer une permission ou un jeu
d'autorisations de la mthode concerne (Elle va crer une liste noire des permissions
effectives sur la mthode).
PermitOnly : Permet de supprimer toutes les autorisations accordes jusqu'ici et de
n'autoriser que celles qui sont affectes par ce paramtre (Elle va crer une liste
blanche des permissions effectives sur la mthode).
Dans cet exemple, nous crons plusieurs mthodes permettant daccder au fichier C:\test.txt
ainsi quune mthode lanant les deux autres mais qui est quipe dune restriction dclarative :

Date

34

La scurit du .NET Framework

'VB
Imports System.IO
Imports System.Security.Permissions
Public Sub ReadTest()
Dim sr As StreamReader = New StreamReader("c:\test.txt")
sr.Close()
End Sub
Public Sub WriteTest()
Dim sw As StreamWriter = New StreamWriter("c:\test.txt")
sw.Close()
End Sub
<FileIOPermission(SecurityAction.PermitOnly, Read:="C:\test.txt")> _
Public Sub DoneAll()
ReadTest()
WriteTest()
End Sub
Public Sub Main()
Try
Console.WriteLine("Tentative de lecture")
ReadTest()
Console.WriteLine("Tentative d'criture")
WriteTest()
Console.WriteLine("Opration groupe")
DoneAll()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub

Date

35

La scurit du .NET Framework

//C#
using System.IO;
using System.Security.Permissions;
public static void ReadTest()
{
StreamReader sr = new StreamReader(@"C:\test.txt");
sr.Close();
}
public static void WriteTest()
{
StreamWriter sr = new StreamWriter(@"C:\test.txt");
sr.Close();
}
[FileIOPermission(SecurityAction.PermitOnly, Read="C:\test.txt")]
public static void DoneAll()
{
ReadTest();
WriteTest();
}
public static void Main(string[] args)
{
try
{
Console.WriteLine("Tentative de lecture");
ReadTest();
Console.WriteLine("Tentative d'criture");
WriteTest();
Console.WriteLine("Opration groupe");
DoneAll();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}

Tentative de lecture
Tentative d'criture
Opration groupe
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPe
rmission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56193
4e089'.
Nous constatons quaucune exception nest leve si nous passons par lune des mthodes
ReadTest ou WriteTest. En revanche, si nous appelons la mthode DoneAll, laccs en criture
chouera.
Le rsultat aurait t strictement identique si nous avions remplac
"SecurityAction.PermitOnly, Read" par "SecurityAction.Deny, Write ". La seule
diffrence est que dans ce cas-ci, nous n'autorisons que la lecture et dans l'autre, nous interdisons
l'criture.

Date

36

La scurit du .NET Framework

Nous pouvons galement effectuer les mmes oprations de faon imprative :


'VB
Dim restrict As FileIOPermission
Public Sub Main()
restrict = New FileIOPermission(FileIOPermissionAccess.Write,
"C:\test.txt")
Try
restrict.Demand()
Console.WriteLine("Tentative de lecture")
ReadTest()
Console.WriteLine("Tentative d'criture")
WriteTest()
restrict.Deny()
Console.WriteLine("Opration groupe")
DoneAll()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub
//C#
private static FileIOPermission restrict;
public static void Main(string[] args)
{
restrict = new FileIOPermission(FileIOPermissionAccess.Write,
"C:\test.txt");
try
{
restrict.Demand();
Console.WriteLine("Tentative de lecture");
ReadTest();
Console.WriteLine("Tentative d'criture");
WriteTest();
restrict.Deny();
Console.WriteLine("Opration groupe");
DoneAll();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}

Ce code donnera le mme rsultat que ci-dessus.


Important : Lorsque vous traitez vos exceptions, prfrez utiliser la valeur PermitOnly. En
effet, celle-ci est par dfinition beaucoup plus restrictive que Deny. Cela permet d'viter qu'un pirate
informatique utilise vos gestions d'erreurs afin de provoquer des comportements inhabituels de
votre application.
Il se peut que vous ayez besoin de restreindre un ensemble de permissions dans une mthode.
Vous allez pouvoir utiliser la classe PermissionSet. Celle-ci va vous permettre de crer un groupe
de permissions reprsente par un seul objet.
Voici un exemple :

Date

37

La scurit du .NET Framework

//C#
Imports System.IO
Imports System.Security.Permissions
Imports System.Security
Dim permissions As PermissionSet = New
PermissionSet(PermissionState.None)
permissions.AddPermission(New
FileIOPermission(FileIOPermissionAccess.Write, "C:\test.txt"))
permissions.AddPermission(New
FileIOPermission(FileIOPermissionAccess.Write, "C:\test1.txt"))
permissions.Demand()
//C#
using System.Security.Permissions;
using System.IO;
using System.Security;
PermissionSet permissions = new PermissionSet(PermissionState.None);
permissions.AddPermission(new
FileIOPermission(FileIOPermissionAccess.Write, @"C:\test.txt"));
permissions.AddPermission(new
FileIOPermission(FileIOPermissionAccess.Write, @"C:\test1.txt"));
permissions.Demand();

Il peut tre intressant galement de transformer lobjet PermissionSet en XML pour pouvoir
limporter ensuite dans dautres mthodes. Pour cela vous devrez utiliser la mthode ToXml. Voici ce
qui ressort si nous convertissons le PermissionSet ci-dessus en XML :
<PermissionSet class="System.Security.PermissionSet"version="1">
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Write="C:\test.txt;C:\test1.txt"/>
</PermissionSet>
Note : Toute classe base sur CodeAccessPermission possde galement les mthodes ToXml et
FromXml.

3.3 Effectuer des demandes groupes


Pour des raisons videntes de performance de votre programme, il est possible d'viter de
faire des demandes de droits chaque fois que nous en avons besoin. Pour cela, vous pouvez faire de
deux faons :
En utilisant LinkDemand. Cette mthode est pratique mais peut constituer un trou de
scurit important. En effet, si les autorisations sont accordes dans le sens
descendant de la pile d'appel, partir du moment o une ligne possde un attribut
LinkDemand, les autorisations ne seront plus vrifies au moment o la pile d'appel
est vide ; Seulement, les anciens droits d'accs ne pourront pas tre restaurs leur
tat d'origine. Ainsi, un code malicieux se trouvant tout en haut de la pile d'appel
pourrait profiter des droits accords par la mthode quipe de LinkDemand afin
d'excuter du code non-dsirable.
En utilisant Assert. Cette mthode est similaire LinkDemand la nuance prs que
lorsque l'autorisation a t accorde, elle est supprime par la suite. Ainsi, l o
LinkDemand laissera des droits l'application, Assert restaurera les restrictions
d'accs. Une mthode se trouvant en haut de la pile d'appel ne pourra plus excuter
de code en profitant des droits accords temporairement.

Date

38

La scurit du .NET Framework

Note : Aucun exemple ne peut tre facilement fourni avec LinkDemand. En effet, LinkDemand
est plus complexe illustrer et il agit au moment de la compilation JIT plutt qu'a l'excution du
programme.
Voici un exemple avec Assert dans lequel nous appelons 2 mthodes qui tentent une criture
sur un fichier dont l'accs est interdit en criture :
'VB
<FileIOPermission(SecurityAction.Deny, Write:="C:\test.txt")> _
Public Sub Main()
Try
Console.WriteLine("Tentative d'opration groupe")
DoneAll()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Try
Console.WriteLine("Ecriture a partir de Main")
Dim sw As StreamWriter = New StreamWriter("c:\test.txt")
sw.Close()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub
Public Sub WriteTest()
Dim sw As StreamWriter = New StreamWriter("c:\test.txt")
sw.Close()
End Sub
<FileIOPermission(SecurityAction.Assert, Write:="C:\test.txt")> _
Public Sub DoneAll()
Dim sw As StreamWriter = New StreamWriter("c:\test.txt")
sw.Close()
WriteTest()
End Sub

Date

39

La scurit du .NET Framework

//C#
[FileIOPermission(SecurityAction.Deny, Write="C:\test.txt")]
public static void Main(string[] args)
{
try {
Console.WriteLine("Tentative d'opration groupe");
DoneAll();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
try {
Console.WriteLine("Ecriture a partir de Main");
StreamWriter sw = new StreamWriter(@"C:\test.txt");
sw.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.Read();
}
public static void WriteTest()
{
StreamWriter sr = new StreamWriter(@"C:\test.txt");
sr.Close();
}
[FileIOPermission(SecurityAction.Assert, Write="C:\test.txt")]
public static void DoneAll()
{
StreamWriter sw = new StreamWriter(@"C:\test.txt");
sw.Close();
WriteTest();
}

Si nous compilons ce projet, nous obtenons ce rsultat :


Tentative d'opration groupe
Ecriture a partir de Main
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPe
rmission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56193
4e089'.
Dans un premier temps, nous appelons la mthode DoneAll qui est quipe de l'autorisation
en criture avec Assert. Cette autorisation est effective sur la mthode et sur toutes les mthodes
qui se trouvent aprs dans la pile d'appel, ce qui ne lvera aucune exception.
Par contre, si nous tentons d'ouvrir le fichier en criture dans la mthode Main, aprs l'appel
la mthode DoneAll, nous avons une exception de scurit qui est leve.
Afin de vous prouver que les permissions sont analyses en fonction de la pile d'appel,
reprenez l'exemple et supprimez l'attribut plac au dessus de la mthode DoneAll. Cette fois-ci,
mme l'appel de la mthode, vous aurez une exception qui sera leve :
Tentative d'opration groupe
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPe
rmission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56193
4e089'.
Ecriture a partir de Main
chec de la demande d'autorisation de type 'System.Security.Permissions.FileIOPe
rmission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56193
4e089'.
Date

40

La scurit du .NET Framework

4 Scurisation des accs


Nous avons vu dans une premire partie comment scuriser nos applications, nous allons
maintenant voir comment protger les donnes et les utilisateurs de vos applications.
Deux concepts de base connaitre quand on parle de scurit des donnes et des utilisateurs
sont lauthentification et lautorisation :
Lauthentification est le fait de vrifier lidentit dun utilisateur. Par exemple en lui
demandant son login et mot de passe et en vrifiant que les bonnes donnes ont t
entres.
Lautorisation permet de vrifier quun utilisateur, identifi ou non, a le droit daccder
certaines ressources.
Gnralement, authentification et autorisation sont jumeles afin de maximiser la scurit
dun systme.

Date

41

La scurit du .NET Framework

4.1 Authentification
Le Framework .NET propose deux classes permettant de reprsenter un utilisateur ou un
groupe dutilisateur. Grce ces deux classes nous allons pouvoir couvrir les besoins basiques de
lauthentification.
Ces
deux
classes
se
trouvent
dans
lespace
de
nom
System.Security.Principal.
Note : Ces deux classes ne fonctionnent que sous un environnement Windows.
4.1.1

Authentification avec WindowsIdentity


La classe WindowsIdentity permet de reprsenter un compte utilisateur sur les systmes
dexploitation Windows. Vous ne pouvez pas authentifier un utilisateur auprs de votre application
avec WindowsIdentity mais vous allez pouvoir rcuprer, partir du compte utilisateur
authentifi, le nom d'un utilisateur prsent dans la base de donnes Active Directory, un jeton
dauthentification et le rsultat de lauthentification.
Voici les principaux membres de la classe WindowsIdentity :
Membres
Description
GetAnonymous
Mthode Statique, elle retourne un objet WindowsIdentity qui
reprsente un utilisateur anonyme.
GetCurrent
Mthode Statique, elle retourne un objet WindowsIdentity qui
reprsente lutilisateur courant.
Impersonate
Impersonate possde une surcharge statique et une autre non
statique :
La mthode statique prend un IntPtr en paramtre
reprsentant le jeton dun utilisateur. Retourne un objet
WindowsIdentity possdant lidentit de lutilisateur reprsent
par le jeton.
La mthode non statique permet demprunter lidentit de
lutilisateur reprsent par lobjet WindowsIdentity
AuthenticationType
Retourne le type dauthentification utilis pour identifier lutilisateur.
Groups
Retourne les groupes auxquels lutilisateur appartient
IsAnonymous
Indique si lutilisateur est identifi comme anonyme.
IsAuthenticated
Indique si lutilisateur a t authentifi par Windows.
IsGuest
Indique si lutilisateur a t authentifi comme compte Guest par
Windows.
IsSystem
Indique si lutilisateur a t authentifi comme compte System par
Windows.
Name
Obtient le nom dutilisateur utilis lors de sa connexion. Le nom est
compos du nom du Domaine puis du nom dutilisateur, exemple :
SCHMAC\Paul
Owner
Obtient lidentificateur de scurit (SID) de lutilisateur propritaire du
jeton.
Token
Obtient le jeton du compte utilisateur.
User
Obtient lidentificateur de scurit (SID) de lutilisateur.

Date

42

La scurit du .NET Framework

Voici un exemple dutilisation trs simple de WindowsIdentity. Nous rcuprons lidentit


du compte utilisateur courant et affichons son nom dutilisateur avec la proprit Name :
'VB
Imports System.Security.Principal
Sub Main()
Dim IdentiteUtilisateur As WindowsIdentity =
WindowsIdentity.GetCurrent()
Console.WriteLine("Nom : " + IdentiteUtilisateur.Name)
Console.Read()
End Sub
//C#
using System.Security.Principal;
static void Main()
{
WindowsIdentity IdentiteUtilisateur = WindowsIdentity.GetCurrent();
Console.WriteLine("Nom : " + IdentiteUtilisateur.Name);
Console.Read();
}

Nom : SCHMAC\Paul
4.1.2

Cration d'une classe d'identit personnalise


Nous avons vu juste avant la classe WindowsIdentity qui nous permet de reprsenter un
utilisateur du Systme sous forme dun objet. Cette classe built-in drive de linterface IIdentity.
Afin de crer une classe didentit personnalise, vous devrez implmenter l'interface IIdentity.
Voici les trois proprits que vous devrez implmenter obligatoirement :
AuthenticationType : Cest une chaine de caractre (string) qui indique quel type
dauthentification a t utilise pour authentifier lutilisateur.
IsAuthenticated : Cest un boolen indiquant si lutilisateur est authentifi ou non.
Name : Cest une chaine de caractre reprsentant le nom de lutilisateur.
Ces proprits tant par convention en lecture seule, vous devrez assigner vos valeurs soit par
le constructeur de la classe, soit par une mthode.
Vous aurez sans doute besoin de crer vos propres classes d'identification si vous souhaitez
utiliser un service autre que ceux dont le support est fourni par le Framework 2.0 (Une base de
donnes, un logiciel de gestion a distance, etc).
4.1.3

Authentification d'un groupe d'utilisateurs


Pour authentifier un utilisateur selon son groupe dutilisateur, nous allons utiliser la classe
WindowsPrincipal. Pour rcuprer lobjet WindowsPrincipal correspondant lidentit de
lutilisateur, nous devons passer lobjet WindowsIdentity au constructeur de
WindowsPrincipal :
'VB
Sub Main()
Dim IdentiteUtilisateur As WindowsIdentity =
WindowsIdentity.GetCurrent()
Dim GroupeUtilisateur = New WindowsPrincipal(IdentiteUtilisateur)
End Sub

Date

43

La scurit du .NET Framework

//C#
static void Main()
{
WindowsIdentity IdentiteUtilisateur = WindowsIdentity.GetCurrent();
WindowsPrincipal GroupeUtilisateur = new
WindowsPrincipal(IdentiteUtilisateur);
}

Nous rcuprons lidentit de lutilisateur courant et rcuprons ses informations de groupe


en passant IdentiteUtilisateur au constructeur de WindowsPrincipal.
Il existe une autre manire de crer notre objet WindowsPrincipal, sans utiliser
WindowsIdentity. Vous pouvez directement extraire un objet WindowsPrincipal du thread
courant. En effet le thread courant possde un contexte dexcution et possde donc les
informations ncessaires la cration dun objet WindowsPrincipal pour lutilisateur courant.
Tout dabord vous devrez configurer les paramtres de scurit du thread afin quils utilisent
les paramtres de scurit de Windows plutt que ceux utiliss par dfaut au dmarrage de
l'application.
Ensuite
vous
devrez
caster
en
WindowsPrincipal
lobjet
Thread.CurrentPrincipal.
'VB
Imports System.Threading
Sub Main()
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsP
rincipal)
Dim GroupeUtilisateur As WindowsPrincipal =
CType(Thread.CurrentPrincipal, WindowsPrincipal)
End Sub
//C#
using System.Threading;
static void Main()
{
AppDomain.CurrentDomain.SetPrincipalPolicy(
PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal GroupeUtilisateur =
(WindowsPrincipal)Thread.CurrentPrincipal;
}

La classe WindowsPrincipal contient deux membres intressants :


Membres
Description
Identity
Retourne un objet WindowsIdentity avec lidentit de lutilisateur.
IsInRole
Retourne si lutilisateur fait partie ou non du groupe pass en
paramtre.
Dans le cas de WindowsPrincipal, les rles sont les groupes utilisateurs du systme
Windows.
Nous allons voir grce un exemple trois faons dutiliser la mthode IsInRole :
La premire mthode consiste passer une valeur de lnumration WindowsBuiltInRole
en tant que paramtre
La seconde mthode consiste passer sous forme de chaine de caractre le nom du groupe
La troisime mthode consiste passer sous forme de chaine de caractre le nom du
domaine suivi dun antislash \ et du nom du groupe.

Date

44

La scurit du .NET Framework

'VB
Sub Main()
Dim IdentiteUtilisateur As WindowsIdentity =
WindowsIdentity.GetCurrent()
Dim GroupeUtilisateur = New WindowsPrincipal(IdentiteUtilisateur)
If (GroupeUtilisateur.IsInRole(WindowsBuiltInRole.Administrator))
Then
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie
des Administrateurs")
End If
If (GroupeUtilisateur.IsInRole("Utilisateurs")) Then
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie
des Utilisateurs locaux")
End If
If (GroupeUtilisateur.IsInRole("TEST\Utilisateurs")) Then
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie
des Utilisateurs du domaine TEST")
End If
End Sub
//C#
Console.Read()
static
End Subvoid Main()
{
WindowsIdentity IdentiteUtilisateur = WindowsIdentity.GetCurrent();
WindowsPrincipal GroupeUtilisateur = new
WindowsPrincipal(IdentiteUtilisateur);
if (GroupeUtilisateur.IsInRole(WindowsBuiltInRole.Administrator))
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie des
Administrateurs");
if (GroupeUtilisateur.IsInRole(@"Utilisateurs"))
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie des
Utilisateurs locaux");
if (GroupeUtilisateur.IsInRole(@"TEST\Utilisateurs"))
Console.WriteLine(IdentiteUtilisateur.Name + " fait partie des
Utilisateurs du domaine TEST");
Console.Read();
}

SCHMAC\Paul fait partie des Administrateurs


SCHMAC\Paul fait partie des Utilisateurs locaux
Nous avons utilis successivement les trois mthodes dans cet exemple. Dans la premire nous
vrifions si lutilisateur fait partie du groupe des administrateurs, cest le cas, la condition est donc
bonne on affiche que lutilisateur fait partie des Administrateurs.
Dans le second cas, on vrifie si lutilisateur fait partie du groupe Utilisateurs, cest le cas on
laffiche. Il nest pas intressant dutiliser cette mthode pour vrifier une valeur contenue dans
lnumration WindowsBuiltInRole, vous utiliserez plutt cette faon de faire pour vrifier
lappartenance de notre utilisateur un groupe que vous avez cre.
Enfin dans le dernier cas, nous rajoutons un domaine - TEST- comme notre utilisateur ne fais
pas partie du domaine TEST, la condition nest pas vrifie et rien nest affich.

Date

45

La scurit du .NET Framework

4.1.4

Cration de classe d'identit de groupe personnalise


Tout comme WindowsIdentity hrite de IIdentity, WindowsPrincipal hrite de
linterface IPrincipal. Pour crer une classe didentit de groupe personnalise, vous devrez donc
hriter et implmenter IPrincipal.
Votre classe devra obligatoirement comporter un constructeur qui va permettre de rcuprer
les informations didentit d'un objet IIdentity, la mthode IsInRole, et la proprit Identity.
4.1.5

Authentification gnrique
Avec WindowsIdentity, nous avons cre un objet reprsentant lidentit dun utilisateur
Windows. WindowsPrincipal reprsentait lui les groupes utilisateurs auquel lutilisateur
appartient. Il y a plusieurs autres types dutilisateurs et de groupes dutilisateurs que vous pouvez
avoir besoin de reprsenter. Dans la plupart des cas, vous devrez crer vos propres classes
implmentant IIdentity et IPrincipal. Le Framework .NET fournit malgr tout deux autres
classes permettant de reprsenter utilisateur et groupe dutilisateurs : GenericIdentity et
GenericPrincipal.
Ces deux classes permettent de crer des utilisateurs virtuels afin de grer facilement les
droits dune application simple. Voici un exemple de cration des objets GenericIdentity et
GenericPrincipal :
'VB
Sub Main()
Dim utilisateur As GenericIdentity = New GenericIdentity("Toto",
"Biometrie")
Dim roles() As String = New String() {"Utilisateurs",
"Administrateurs"}
Dim GroupeGenerique As GenericPrincipal = New
GenericPrincipal(utilisateur, roles)
End Sub
//C#
static void Main()
{
GenericIdentity utilisateur = new GenericIdentity("Toto",
"Biometrie");
string[] roles = new string[] { "Utilisateurs", "Administrateurs" };
GenericPrincipal GroupeGenerique = new GenericPrincipal(utilisateur,
roles);
}

Dabord nous crons lobjet GenericIdentity, nous mettons en paramtre son nom
dutilisateur, et la mthode dauthentification.
Ensuite nous instancions lobjet GenericPrincipal, nous passons en paramtre lobjet
GenericIdentity prcdent, et un tableau des rles auquel il appartient, Users et Administrators.

Date

46

La scurit du .NET Framework

Si vous voulez maintenant faire en sorte que les paramtres de scurit du Thread soient
associs cet utilisateur gnrique, il suffit de placer votre identit gnrique dans la proprit
CurrentPrincipal du thread :
'VB
Sub Main()
Dim utilisateur As GenericIdentity = New GenericIdentity("Toto",
"Biometrie")
Dim roles() As String = New String() {"Utilisateurs",
"Administrateurs"}
Dim GroupeGenerique As GenericPrincipal = New
GenericPrincipal(utilisateur, roles)
Thread.CurrentPrincipal = GroupeGenerique
Console.WriteLine(Thread.CurrentPrincipal.Identity.Name)
Console.Read()
End Sub
//C#
static void Main()
{
GenericIdentity utilisateur = new GenericIdentity("Toto",
"Biometrie");
string[] roles = new string[] { "Users", "Administrators" };
GenericPrincipal GroupeGenerique = new GenericPrincipal(utilisateur,
roles);
Thread.CurrentPrincipal = GroupeGenerique;
Console.WriteLine(Thread.CurrentPrincipal.Identity.Name);
Console.Read()
}

Toto
Nous associons notre objet GenericPrincipal Thread.CurrentPrincipal et pour
vrifier, on affiche Identity.Name.

Date

47

La scurit du .NET Framework

4.2 Autorisation
Dans le processus de scurisation des donnes, lautorisation est une phase cl de laccs aux
donnes. En effet, sans elle, il vous sera impossible davoir accs une partie des ressources.
Le .NET Framework vous donne la possibilit de vrifier que lutilisateur qui excute votre code
possde bien le bon rle (autrement dit, quil adhre au groupe dutilisateur ayant les droits
suffisants pour effectuer cette opration). Pour cela, vous utiliserez soit la classe PrincipalPermission
(pour le test de faon imprative) soit lattribut PrincipalPermission (pour le test de faon
dclarative).
Ces
deux
lments
se
trouvent
dans
l'espace
de
nom
System.Security.Permissions.
En ce qui concerne la mthode dclarative, vous pouvez spcifier les paramtres suivant :
Name : Reprsente le nom complet de l'entit vrifier. Par exemple, si nous
souhaitons autoriser l'utilisateur "Jean" sur la machine "Pc-Familial", le nom complet
serait "Pc-Familial\Jean" ("Pc-Familial" reprsente le domaine dans lequel se trouve la
machine. Si vous vous authentifiez sur un rseau portant un nom de domaine, vous
devrez spcifier le domaine suivi du login de l'utilisateur)
Authenticated : Spcifie un boolen indiquant si l'utilisateur doit tre authentifi ou
non.
Role : Indique le nom du groupe d'utilisateur dans lequel on doit se trouver pour
correspondre aux critres de recherche.
SecurityAction : Indique l'action de scurit entreprendre (demande, interdiction, )
Si vous prfrez utiliser la faon imprative, les constructeurs de la classe PrincipalPermission
vous permettent de spcifier :
Name : Le nom d'utilisateur (comme pour la mthode dclarative)
Role : Le nom du groupe d'utilisateur (comme pour la mthode dclarative)
Authenticated : La restriction d'authentification (comme pour la mthode dclarative)
Ou alors l'un des valeurs de l'numration PermissionState. Cette numration vous fourni
deux valeurs :
None : Qui indique que l'utilisateur n'a aucun accs aux ressources
Unrestricted : Qui indique que l'utilisateur a un accs total aux ressources.

Date

48

La scurit du .NET Framework

Dans le code suivant, nous avons cr une mthode qui a besoin quun utilisateur authentifi
et ayant les droits dadministration excute lapplication. Si lutilisateur courant ne respecte pas lune
de ces conditions, une exception sera leve :
VB
Imports System.Security.Permissions
Sub Main()
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsP
rincipal)
Try
Admin()
Catch ex As Exception
Console.WriteLine("Autorisation refuse" + vbNewLine +
ex.Message)
End Try
Console.Read()
End Sub
<PrincipalPermission(SecurityAction.Demand, Authenticated:=True,
Role:="Administrateurs")> _
Public Sub Admin()
Console.WriteLine("Autorisation accorde!")
End Sub
//C#
using System.Security.Permissions;
static void Main()
{
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincip
al);
try
{
Admin();
}
catch (Exception ex)
{
Console.WriteLine("Autorisation refuse\n" + ex.Message);
}
Console.Read();
}
[PrincipalPermission(SecurityAction.Demand, Authenticated=true,
Role="Administrateurs")]
public static void Admin()
{
Console.WriteLine("Autorisation accorde!");
}

Si lutilisateur authentifi actuellement fait partit du groupe "Administrateurs", nous aurons le


rsultat suivant :
Autorisation accorde!
Dans le cas contraire, l'exception sera leve et la mthode ne sera pas excute :
Autorisation refuse
chec de la demande d'autorisation principale.

Date

49

La scurit du .NET Framework

5 Gestion de la RBS Windows


Dans le prambule de ce chapitre, nous avions abord la scurit de la CLR en faisant une
analogie avec le systme de scurit utilis par Windows pour protger l'accs aux ressources
(fichiers, base de registre, connexions rseaux, ) des utilisateurs non-autoriss.
Dans cette partie, nous revenons sur le systme RBS afin de voir comment le Framework peut
agir sur ce systme afin de rgler les paramtres de scurit.

5.1 Rappel sur le systme RBS Windows


En entreprise, il n'est pas rare que des employs doivent se servir de l'outil informatique.
Seulement, sans systme de protection, un employ peu qualifi en ce qui concerne l'utilisation d'un
ordinateur peut rapidement devenir un dsavantage considrable pour l'entreprise (Imaginez si un
employ d'une banque venait supprimer par erreur toutes les transactions bancaire ralises au
cours des dernires 24 heures).
Pour cela, les machines quipes d'un systme Windows utiliseront un systme d'utilisateurs
et de groupe d'utilisateurs ; Chacun d'entres eux possdant des droits (ou rle) bien dfinit.
Si vous faites clic-droit sur un fichier, un dossier ou un disque dur, que vous faites proprits
puis que vous saisissez l'onglet "Scurit", vous aurez accs la gestion des droits sur l'lment
concern (Attention : Sur certaines machines, notamment celles quipes de versions dites
"familiale" de Windows, vous devez configurer l'affichage des proprits pour avoir accs la
scurit) :

Dans le premier encadr, vous avez la liste des entits dont les droits sont modifis (accepts
ou refuss) sur l'lment et dans l'encadr du dessous, vous avez la liste des droits effectifs appliqus
l'entit slectionne au dessus.
Date

50

La scurit du .NET Framework

Si vous cliquez sur le bouton "Avanc" :

Vous aurez accs aux informations prcises concernant la scurit de l'lment :


Autorisations : Cet onglet vous permet de visualiser ou modifier les droits effectifs sur
les entits indiques. Il vous permettra galement de savoir si une permission est
hrite de son conteneur parent ou non. Si la permission est effectivement hrite,
vous devrez soit modifier les permissions du conteneur parent ou bien dsactiver
l'hritage des permissions sur l'lment courant (case grise sur ce Screenshot. Il faut
cliquer sur "Modifier" pour changer cette option). Toute cette section vous permettra
de rgler la liste de contrle d'accs discrtionnaire (DACL pour Discretionary Access
Control List)
Audit : Il va vous permettre de grer l'audit de l'lment en cours. Un audit, c'est le fait
de surveiller toute action ralise sur la ressource concerne, que a soit la lecture, la
modification, la suppression, le partage, . Vous pourrez grer ce qu'on appelle les
listes de contrle d'accs de scurit (SACL pour Security Access Control List). Retenez
bien que les SACL ne rglent aucune restriction d'accs. Elles se contentent juste de
paramtrer la surveillance (l'audit) de la ressource!
Autorisations effectives : Cet onglet vous permet de tester quels sont les droits dont
dispose un utilisateur ou un groupe sur la ressource en cours. Il vous suffit de saisir
l'entit que vous souhaitez tester et de valider pour voir s'afficher les droits dont elle
dispose ; Trs pratique lorsque vous configurez des rgles complexes en utilisant
plusieurs groupes diffrents.
En regardant un peu ces droits d'accs, vous aurez rapidement constat que c'est donc ici que
l'on paramtrera qui peut avoir accs en lecture, en criture .

Date

51

La scurit du .NET Framework

5.2 Gestion des droits via le code


S'il est possible de modifier les droits d'accs aux ressources en passant par le systme
d'exploitation, il est galement possible de les modifier en utilisant les outils de l'espace de nom
System.Security.AccessControl.
Dans cet espace de noms, vous trouverez tous les outils ncessaires la vrification et la
modification des droits d'accs aux ressources. De faon gnrale, vous trouverez les types de classes
suivants :
<Ressources>Security (par exemple RegistrySecurity) qui vous permettra de
visualiser/modifier aussi bien les listes DACL que les listes SACL.
<Ressources>AccessRule (par exemple RegistryAccessRule) qui vous permettra de
visualiser/modifier les DACL.
<Ressources>AuditRule (par exemple RegistryAuditRule) qui vous permettra de
visualiser/modifier les SACL.
Par dfaut, le Framework implmente la classe NativeObjectSecurity pour diffrentes
ressources :
FileSystemSecurity, pour le systme de fichier.
FileSecurity, qui est spcifique aux fichiers
RegistrySecurity, permettant la gestion de l'accs au registre Windows
MutexSecurity, pour la scurit inter-application des Mutex (voir chapitre 7)
SemaphoreSecurity, identique MutexSecurity mais pour les Smaphores
EventWaitHandleSecurity, pour la gestion des WaitHandle (voir chapitre 7)
DirectorySecurity, qui est spcifique aux dossiers.
Grce l'une de ces classes, vous allez pouvoir altrer les droits d'accs l'un des lments
cits ci-dessus.
Comme exemple, nous allons lister les droits appliqus au fichier C:\test.txt puis nous allons
ajouter le droit de suppression et de modification au groupe d'utilisateurs "Utilisateurs" :
VB
Imports System.Security.AccessControl
Imports System.Security.Principal
Imports System.IO
Sub Main()
Dim fichier As String = "C:\test.txt"
Dim secu As FileSecurity = New FileSecurity(fichier,
AccessControlSections.All)
Dim dacl As AuthorizationRuleCollection = secu.GetAccessRules(True,
True, GetType(NTAccount))
For Each ar As FileSystemAccessRule In dacl
Console.WriteLine(ar.IdentityReference.Value + " a le(s)
droit(s) " + ar.FileSystemRights.ToString())
Next
Dim ndacl As FileSystemAccessRule = New
FileSystemAccessRule("Utilisateurs", FileSystemRights.Delete Or
FileSystemRights.Modify, AccessControlType.Allow)
secu.AddAccessRule(ndacl)
File.SetAccessControl(fichier, secu)
Console.Read()
End Sub

Date

52

La scurit du .NET Framework

//C#
using System.Security.AccessControl;
using System.Security.Principal;
using System.IO;
static void Main(string[] args)
{
string fichier = @"C:\test.txt";
FileSecurity secu = new FileSecurity(fichier,
AccessControlSections.All);
AuthorizationRuleCollection dacl =
secu.GetAccessRules(true,true,typeof(NTAccount));
foreach(FileSystemAccessRule ar in dacl)
Console.WriteLine(ar.IdentityReference.Value + " a le(s) droit(s)
" + ar.FileSystemRights.ToString());
FileSystemAccessRule ndacl = new FileSystemAccessRule("Utilisateurs",
FileSystemRights.Delete | FileSystemRights.Modify,
AccessControlType.Allow);
secu.AddAccessRule(ndacl);
File.SetAccessControl(fichier, secu);
Console.Read();
}

Dans la console, vous devriez avoir un rsultat similaire celui-ci :


AUTORITE NT\Utilisateurs authentifis a le(s) droit(s) Modify, Synchronize
AUTORITE NT\SYSTEM a le(s) droit(s) FullControl
BUILTIN\Administrateurs a le(s) droit(s) FullControl
BUILTIN\Utilisateurs a le(s) droit(s) ReadAndExecute, Synchronize
Et si vous allez regarder la scurit du fichier, vous devriez obtenir ce changement ( gauche, la
scurit avant excution du programme. A droite, la scurit aprs excution) :

Date

53

La scurit du .NET Framework

Dans l'exemple, vous aurez pu constater que lorsqu'on demande rcuprer la liste DACL ou
SACL, trois paramtres sont ncessaires. Les deux premiers indiquent respectivement si la recherche
doit inclure les droits spcifiques l'lment et les droits hrits du conteneur parent. Le troisime
paramtre est un objet de type Type reprsentant le "formatage" utilis pour reprsenter les entits.
Vous ne pouvez pas y passer n'importe quel type! Vous ne pourrez utiliser que :
Le type System.Security.Principal.NTAccess, pour obtenir une
reprsentation sous forme de texte des entits.
Le type System.Security.Principal.SecurityIdentifier, permettant
d'obtenir une reprsentation en utilisant les identifiants numriques des entits (SID).
Important : Pour pouvoir modifier les droits d'accs une ressource, vous devez, que a
soit via le systme d'exploitation ou via le code, possder le droit de modification des
rgles de scurit. Par exemple, sous Windows Vista, vous ne pourrez pas modifier les
permissions sur C:\Windows tant que vous tes un membre du groupe Utilisateurs ou
Administrateurs!

Date

54

La scurit du .NET Framework

6 La cryptographie dans le .NET


Scuriser les donnes au niveau de l'application est dj une trs bonne chose. Cependant, il
est tout aussi important de brouiller les donnes importantes qui seront stockes ou changes via
un rseau. Aussi, pour cela, le .NET Framework implmente peu prs toutes les techniques de
cryptographie traditionnelle. Cela inclus les mthodes de cryptage/dcryptage de donnes, la
signature de celles-ci ou encore le contrle d'intgrit.

6.1 Empreintes des donnes


On appelle empreinte de donnes (ou code de hachage) toutes combinaisons d'octets qui,
calcule partir d'algorithme particulier, identifie de faon unique des donnes. Ils permettent de
vrifier l'intgrit des donnes. Ces codes de hachage ont toujours une taille de sortie fixe (plus ou
moins grande en fonction de l'algorithme utilis). Elle peut donc tre suprieure la taille des
donnes dont on veut l'empreinte.
Dans les mthodes de calcul des empreintes de hachage, on distingue deux types d'algorithme:
Les algorithmes sans cl, c'est--dire qu'ils ne prennent en entre que les donnes dont on
souhaite l'empreinte et retournent une srie d'octets reprsentant l'empreinte numrique des
donnes.
Les algorithmes cl ou algorithmes HMAC. Pour calculer une empreinte des donnes, ces
algorithmes ncessitent une cl secrte en plus des donnes afin de protger l'empreinte gnre. Ils
sont en gnral un ajout aux algorithmes sans cls (Par exemple HMAC-MD5, version avec cl de
l'empreinte MD5) et de ce fait sont utilisables avec n'importe quel algorithme de calcul d'empreinte
( partir du moment o cette mthode utilise une itration dans le calcul de l'empreinte). Ils sont
utiliss dans le cas o les personnes changeant des donnes peuvent galement changer la cl
secrte utilise pour gnrer le code de hachage.
Le Framework .NET fourni un ensemble de classes hritant de la classe HashAlgorithm pour
les algorithmes de hachage sans cl ou de la classe KeyedHashAlgorithm pour les algorithmes de
hachage avec cl qui permettent de calculer l'empreinte numrique de donnes :
Classe
Description
MD5CryptoServiceProvider Hachage MD5 gnrant des empreintes de 128bits
SHA1Managed
Hachage SHA gnrant des empreintes de 160bits
RIPEMD160Managed
Hachage MD160 gnrant des empreintes de 160bits
SHA256Managed
Hachage SHA gnrant des empreintes de 256bits
SHA384Managed
Hachage SHA gnrant des empreintes de 384bits
SHA512Managed
Hachage SHA gnrant des empreintes de 512bits
MACTripleDES
Hachage cl secrte en utilisant l'algorithme 3DES.
HMACMD5, HMACSHA1
Hachage cl secrte en utilisant l'un des algorithmes MD5,
SHA1
Toutes les classes de gnration d'empreintes bases sur l'algorithme SHA disposent de deux
versions : Une version entirement manage (classes SHA<version>Managed) et une version
d'adaptation des algorithmes implments dans le service de chiffrement Windows (classes
SHA<version>CryptoServiceProvider).

Date

55

La scurit du .NET Framework

Dans l'exemple ci-dessous, nous calculons une empreinte SHA256 protge avec une cl et
une autre non protge.
'VB
Imports System.Security.Cryptography
Imports System.Text
Imports System.IO
Sub Main()
Dim rfc As Rfc2898DeriveBytes = New Rfc2898DeriveBytes("Mot de
passe", 12)
Dim hsha256 As HMACSHA256 = New HMACSHA256(rfc.GetBytes(64))
Dim sha256 As SHA256Managed = New SHA256Managed()
Dim b() As Byte = Encoding.Unicode.GetBytes("Phrase Hache")
hsha256.ComputeHash(b)
sha256.ComputeHash(b)
Console.WriteLine(hsha256.HashName + " gnre l'empreinte " +
Convert.ToBase64String(hsha256.Hash) + " protge par la cl " +
Convert.ToBase64String(hsha256.Key))
Console.WriteLine("SHA256 gnre l'empreinte " +
Convert.ToBase64String(sha256.Hash))
Console.Read()
End Sub
//C#
using System.Security.Cryptography;
using System.Text;
using System.IO;
static void Main(string[] args)
{
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes("Mot de passe", 12);
HMACSHA256 hsha256 = new HMACSHA256(rfc.GetBytes(64));
SHA256Managed sha256 = new SHA256Managed();
byte[] b = Encoding.Unicode.GetBytes("Phrase Hache");
hsha256.ComputeHash(b);
sha256.ComputeHash(b);
Console.WriteLine(hsha256.HashName + " gnre l'empreinte " +
Convert.ToBase64String(hsha256.Hash) + " protge par la cl " +
Convert.ToBase64String(hsha256.Key));
Console.WriteLine("SHA256 gnre l'empreinte " +
Convert.ToBase64String(sha256.Hash));
Console.Read();
}

Date

56

La scurit du .NET Framework

Lors de la compilation, nous constatons que l'empreinte protge par mot de passe est
toujours diffrente de la prcdente. Ceci s'explique par le fait que nous utilisons la classe
Rfc2898DeriveBytes qui se charge de gnrer une cl pseudo-alatoire en se basant sur la phrase
passe en argument. L'empreinte calcule en utilisant SHA256 seul est toujours la mme.
SHA256 gnre l'empreinte tW5Ij4Lr32uJBvZD1ezSI5yyg6p4R4E1aUcyrNyW2PI= protge par la cl
bEB8lHiuBb+VpeD2hKZck3BV1Xe/ap+OhGqUPCo2kb00gGJhrfLmT2/BaiaMWqAhZprrg
9Rdtnc38ZaIWmpDcw==
SHA256 gnre l'empreinte qUF3tT1eV8ojg8l8H//ShhoAUEAPUVRj4e4UIlHnF5k=
Mme s'il est trs peu probable que plusieurs donnes diffrentes aient la mme empreinte, il
faut veiller bien choisir l'algorithme de calcul en fonction du niveau de scurit requis. Par exemple,
l'empreinte MD5 commence montrer des faiblesses. Pour des applications demandant un haut
niveau de scurit, prfrez les algorithmes SHA256, 384

Date

57

La scurit du .NET Framework

6.2 Chiffrement symtrique


Le chiffrement par cl symtrique est une mthode de chiffrement simple que vous avez peut
tre eu loccasion dutiliser. Elle consiste utiliser une cl, souvent une suite de caractres, afin de
passer dun texte clair un texte dt chiffr (indescriptible sans traitement pralable) et vice versa.
Lavantage du chiffrement par cl symtrique est la rapidit et la robustesse des algorithmes
de traitement qui permettent de chiffrer de grandes quantits de donnes rapidement et sans perte.
Linconvnient de cette mthode est lutilisation dune seule cl secrte pour chiffrer et
dchiffrer. En effet, si une personne mal intentionne arrive trouver ou rcuprer la cl secrte, il
pourra visionner les donnes en clair. Dautre part, toutes les personnes susceptibles de chiffrer et
dchiffrer les donnes devront schanger la cl secrte en clair.
6.2.1

Outil annexe : La classe Rfc2898DeviveBytes


Sous ce nom trange se cache une classe permettant la gnration de cls secrtes pour les
changes de donnes chiffres par cl symtrique.
Pour crer votre cl secrte, vous allez devoir fournir la classe trois informations :
Un mot de passe ou une phrase transformer
Un Salt donnant la gnration d'octets un caractre pseudo-alatoire plus complexe
retrouver.
Le nombre ditration ncessaire pour la cration de la cl. (facultatif)
La manire la plus simple dutiliser Rfc2898DeriveBytes est de passer les deux donnes au
constructeur de la classe, puis de rcuprer ensuite la cl gnre grce la mthode GetBytes.
Voici un exemple dutilisation :
'VB
Imports System.Security.Cryptography
Imports System.Text
Sub Main()
Dim chaine As String = "MotDePasse"
Dim salt() As Byte = Encoding.ASCII.GetBytes("CeciEstUnSalt")
Dim cle As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(chaine,
salt)
Dim AES As RijndaelManaged = New RijndaelManaged()
AES.Key = cle.GetBytes(AES.KeySize / 8)
End Sub
//C#
using System.Security.Cryptography;
using System.Text;
public static void Main(string[] args)
{
string chaine = "MotDePasse";
byte[] salt = Encoding.ASCII.GetBytes("CeciEstUnSalt");
Rfc2898DeriveBytes cle = new Rfc2898DeriveBytes(chaine, salt);
RijndaelManaged AES = new RijndaelManaged();
AES.Key = cle.GetBytes(AES.KeySize / 8);
}

Cet exemple parat plus complexe quil ne lest vraiment. Nous commenons par crer notre
chaine transformer en cl et notre salt. La chane est un string et le salt un tableau doctets.
Ensuite nous crons notre objet de type Rfc2898DeriveBytes en passant au constructeur notre
chane et notre salt.
Enfin nous instancions un objet reprsentant un algorithme de chiffrement que nous verrons
dans la partie suivante. Ce quil faut en retenir se trouve dans la dernire ligne : Nous rcuprons
Date

58

La scurit du .NET Framework

grce GetBytes la cl et lassocions notre algorithme. Pour rcuprer une cl de la bonne taille,
nous passons en paramtre la taille dsire, ici AES.KeySize reprsente la taille de la cl que ncessite
notre algorithme en bits, que nous divisons par 8 pour obtenir la taille en octets.

Date

59

La scurit du .NET Framework

6.2.2

Le chiffrement symtrique en pratique


Afin deffectuer des chiffrements par cl symtrique, le Framework .NET fournit quelques
classes drivant de System.Security.Cryptography.SymmetricAlgorithm et contenues dans
lespace de nom System.Security.Cryptography.
Nous allons dabord voir en dtail les diffrentes classes puis ensuite leurs membres
communs :
Classes
Longueur de la cl
Description
DES
56 bits
Acronyme de Data Encryption Standard.
Lalgorithme DES permet de chiffrer et dchiffrer
grce des cls trs courtes, de ce fait il est
vulnrable au cracking par brute force. Les
algorithmes RC visent le remplacer.
RC2
Variable
Le RC2 est un standard visant remplacer DES. Il
utiliser des cls de tailles variables.
RijndaelManaged
De 128 bits 256bits Mieux connu sous le nom de AES (Advanced
par pas de 32bits.
Encryption Standard). La classe RijndaelManaged
est la seule qui permet un chiffrement par cl
symtrique en appelant seulement du code
manag. Les autres classes font appel du code
non manag.
TripleDES
156 bits dont 112 bits La classe TripleDES permet dutiliser lalgorithme
pour
le 3DES qui applique trois fois lalgorithme DES afin
chiffrement/dchiffre
damliorer sa rsistance au cracking.
ment
Si nous devions vous conseiller un de ces algorithmes selon un critre de scurit, nous
choisirions Rijndael tout simplement car il permet le chiffrement de donnes en utilisant des cls
secrtes de 256 bits difficilement crackable par une seule personne. De plus il utilise exclusivement
du code manag ce qui le rend plus scuris dans un environnement .NET.

Date

60

La scurit du .NET Framework

Voici maintenant les principaux membres de ces classes qui sont tous hrits de
System.Security.Cryptography.SymmetricAlgorithm :

Membres

Description
Permet dobtenir ou de dfinir la cl secrte. La cl est gnre
automatiquement si aucune nest spcifie.
KeySize
Permet dobtenir ou de dfinir la taille de la cl secrte en bits. Vous
naurez normalement pas besoin de redfinir cette proprit car le
runtime choisit toujours la taille ayant le meilleur rapport
rapidit/scurit.
LegalKeySizes
Reprsente un tableau des tailles des cls secrtes utilisables par
lalgorithme.
Mode
Permet dobtenir ou de dfinir le mode de fonctionnement de
lalgorithme. Pour dfinir le mode de fonctionnement, vous pourrez
utiliser les valeurs de lnumration CipherMode.
IV
Permet de dfinir ou dobtenir le vecteur dinitialisation du
chiffrement/dchiffrement. Ce vecteur est un ensemble de d'octets
utiliss pour raliser le chiffrement du premier paquet d'octets
chiffrer. Voir cet article pour plus de dtails.
CreateDecryptor
Cre un objet permettant le dchiffrement de donnes. Lobjet est de
type ICryptoTransform.
CreateEncryptor
Cre un objet permettant le chiffrement de donnes. Lobjet est de type
ICryptoTransform.
GenerateKey
Gnre une nouvelle cl secrte, vous pourrez appeler cette mthode si
vous souhaitez changer votre cl secrte.
GenerateIV
Gnre un nouveau vecteur dinitialisation.
ValidKeySize
Dtermine si la taille de la cl spcifie est valide pour lalgorithme
choisi.
Afin de pouvoir dchiffrer une donne, vous devrez crer un objet possdant la mme cl, le
mme mode de chiffrement et le mme IV que pour le chiffrement.
Key

Maintenant que nous avons vu quelques bases sur le chiffrement symtrique, nous allons
pouvoir comprendre comment tout cela fonctionne grce un exemple.

Date

61

La scurit du .NET Framework

'VB
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Sub Main()
'(1)
Dim chaine As String = "MotDePasse"
Dim salt() As Byte = Encoding.ASCII.GetBytes("CeciEstUnSalt")
Dim cle As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(chaine,
salt)
Dim AES As RijndaelManaged = New RijndaelManaged()
AES.Key = cle.GetBytes(AES.KeySize / 8)
Dim phrase As String = "Cette phrase va tre chiffre puis
dchiffre"
Dim fichier As String = "C:\test.txt"
'(2)
Dim encryptor As ICryptoTransform = AES.CreateEncryptor(AES.Key,
AES.IV)
'(3)
Dim fichierSortant As FileStream = New FileStream(fichier,
FileMode.Create, FileAccess.Write)
Dim chiffre As CryptoStream = New CryptoStream(fichierSortant,
encryptor, CryptoStreamMode.Write)
Dim ecris As StreamWriter = New StreamWriter(chiffre)
'(4)
ecris.Write(phrase)
ecris.Close()
'(5)
Dim fichierEntrant As FileStream = New FileStream(fichier,
FileMode.Open, FileAccess.Read)
Dim decryptor As ICryptoTransform = AES.CreateDecryptor(AES.Key,
AES.IV)
Dim dechiffre As CryptoStream = New CryptoStream(fichierEntrant,
decryptor, CryptoStreamMode.Read)
Dim lis As StreamReader = New StreamReader(dechiffre)
'(6)
Console.WriteLine(lis.ReadToEnd())
lis.Close()
Console.Read()
End Sub

Date

62

La scurit du .NET Framework

//C#
using System.Security.Cryptography;
using System.IO;
using System.Text;
public static void Main(string[] args)
{
//(1)
string chaine = "MotDePasse";
byte[] salt = Encoding.ASCII.GetBytes("CeciEstUnSalt");
Rfc2898DeriveBytes cle = new Rfc2898DeriveBytes(chaine, salt);
RijndaelManaged AES = new RijndaelManaged();
AES.Key = cle.GetBytes(AES.KeySize / 8);
string phrase = "Cette phrase va tre chiffre puis dchiffre";
string fichier = @"C:\test.txt";
//(2)
ICryptoTransform encryptor = AES.CreateEncryptor(AES.Key, AES.IV);
//(3)
FileStream fichierSortant = new FileStream(fichier, FileMode.Create,
FileAccess.Write);
CryptoStream chiffre = new CryptoStream(fichierSortant, encryptor,
CryptoStreamMode.Write);
StreamWriter ecris = new StreamWriter(chiffre);
//(4)
ecris.Write(phrase);
ecris.Close();
//(5)
FileStream fichierEntrant = new FileStream(fichier, FileMode.Open,
FileAccess.Read);
ICryptoTransform decryptor = AES.CreateDecryptor(AES.Key, AES.IV);
CryptoStream dechiffre = new CryptoStream(fichierEntrant, decryptor,
CryptoStreamMode.Read);
StreamReader lis = new StreamReader(dechiffre);
//(6)
Console.WriteLine(lis.ReadToEnd());
lis.Close();
Console.Read();
}

Cette phrase va tre chiffre puis dchiffre


Pour expliquer cet exemple avec plus de facilit, jai plac dans le code des points de repres
comments ci-dessous.
1) Nous reprenons lidentique lexemple de Rfc2898DeriveBytes
2) Ici nous crons un objet qui va nous permettre de chiffrer la phrase, on le rcupre grce
la mthode CreateEncryptor.
3) Nous crons ici trois flux, et ce afin de ne pas avoir utiliser des tableaux doctets comme
buffer, un flux en criture sur un fichier, un flux de chiffrement pointant sur le flux de
fichier, et un flux StreamWriter qui va piloter le tout.
4) Nous crivons la phrase grce la mthode Write de StreamWriter, les donnes sont
chiffres et crites dans le fichier.
5) Ensuite nous effectuons lopration inverse, nous crons trois flux assez ressemblants, un
sur le fichier en lecture, un qui va se charger de dchiffrer en lisant le fichier et un
StreamReader qui va piloter le tout.
6) Enfin nous affichons le contenu du fichier dchiffr grce la mthode ReadToEnd de
StreamReader.
Date

63

La scurit du .NET Framework

6.3 Chiffrement asymtrique


Le cryptage des donnes de faon asymtrique est plus long effectuer que le cryptage
symtrique mais peut fournir dans certains cas, une scurit accrue. En effet, le cryptage
asymtrique n'utilise plus une seule cl secrte mais deux cls, l'une tant publique et l'autre prive.
La cl prive n'est jamais diffuse et est utilise pour dcrypter les donnes lorsqu'elles sont reues.
La cl publique quand elle est utilise pour crypter les donnes avant leur envoi. Cette dernire est
la seule cl pouvoir tre distribue librement.
Si on se place dans le cas o une personne PA veut recevoir des donnes cryptes de PB de
faon scurise, la personne PA va d'abord gnrer une cl prive qu'elle conservera secrte et une
cl publique qu'elle enverra PB. PB va recevoir la cl publique, encrypter les donnes envoyer en
utilisant cette cl publique et envoyer les donnes cryptes. PA va ensuite recevoir les donnes
cryptes et va pouvoir dcrypter ces donnes grce la cl prive. En admettant que quelqu'un ait
intercept le message crypt et la cl publique, le message resterait indchiffrable facilement vu que
la cl publique ne peut servir qu'au cryptage des donnes.
Du fait de la lenteur du processus de cryptage/dcryptage asymtrique, il n'est, en gnral, pas
utilis pour chiffrer des quantits de donnes importantes. Par exemple, les connexions scurises
SSL/TLS utilisent le cryptage asymtrique pour changer le vecteur d'initialisation et la cl de
chiffrement utiliss par le cryptage symtrique utilis pour chiffrer les donnes transmises.
La classe de base permettant d'implmenter une mthode de cryptage asymtrique est la
classe abstraite AsymmetricAlgorithm qui comporte, en plus des proprits KeySize et
LegalKeySizes les proprits suivantes :
Membres
Description
KeyExchangeAlgorithm Permet d'obtenir l'algorithme d'change des cls utilises.
SignatureAlgorithm
Permet d'obtenir une rfrence vers la signature utilise.
Le Framework propose deux classes qui hritent de AsymmetricAlgorithm. Ces deux classes
sont en fait des outils de gestion (ou wrapper) de code non-manag qui fournissent ces systmes de
cryptage :

Date

64

La scurit du .NET Framework

6.3.1

RSACryptoServiceProvider
Cette classe donne accs au cryptage RSA. Cette mthode de cryptage vous permettra
d'utiliser des cls dont la taille peut aller de 384 bits 16384 bits! En voici les principaux membres :
Membres
Description
Clear
Permet de vider toutes ressources en mmoire utilises par le
RSACryptoServiceProvider.
Decrypt
Permet de dcrypter des donnes cryptes par une cl publique.
Encrypt
Permet d'encrypter des donnes en utilisant la cl publique.
ExportParameters
Exporte les paramtres de cls publiques et/ou prives dans une
structure RSAParameters.
FromXmlString
Importe les paramtres de cls partir d'une chane XML.
ImportParameters
Importe les paramtres de cls partir d'une structure
RSAParameters.
SignData
Cre une signature numrique pour un fichier en deux tapes : dabord
en gnrant un hash et ensuite en gnrant une signature base sur ce
hash.
SignHash
Permet de signer l'empreinte de hash spcifie en utilisant la cl prive.
ToXmlString
Exporte les paramtres de cls sous forme de chaine XML.
VerifyData
Vrifie une signature numrique en la comparant celle produite par
SignData.
VerifyHash
Vrifie une signature numrique base sur le hash du fichier.
PersistKeyInCsp
Indique si le fournisseur de cryptage RSA doit stocker la cl prive dans
le service de chiffrement CryptoAPI*.
UseMachineKeyStore
Proprit statique indiquant si le fournisseur de cryptage RSA doit
stocker la cl prive dans le magasin de cls de l'ordinateur.
PublicOnly
Contient un boolen indiquant si le service de cryptage RSA actuel ne
contient qu'une cl publique.
*Toute machine Windows est quipe d'un service de chiffrement qui permet de stocker les
cls prives dans une section propre l'utilisateur actuel de la base de registre en plus de fournir les
mthodes de chiffrement standard. Vous aurez plus d'informations en visitant la section CryptoAPI
de MSDN ou encore un article concernant le stockage des cls du service de chiffrement.
Voici un exemple concret de l'utilisation du service de cryptage RSA. Cet exemple a t fait de
telle sorte que l'on puisse facilement le transposer sur un dialogue scuris de donnes via un rseau
par exemple.
Nous avons deux mthodes : FournisseurDeDonnees et Destinataire. FournisseurDeDonnees
reprsente la machine que l'on souhaite contacter distance. Elle prendra en paramtre la cl
publique que le destinataire aura prit soin de gnrer avant d'envoyer sa requte.
La mthode Destinataire doit tre appele deux fois : Une premire fois sans arguments ce qui
permettra de gnrer la cl prive et la cl publique et une seconde fois avec la cl prive en
argument afin de lancer le dcryptage des donnes enregistres dans le fichier C:\test.bin.
Afin d'viter d'utiliser des stockages du service de chiffrement de faon inutile, nous allons
utiliser le stockage des cls sous formes d'objets RSAParameters. Dans le cas o vous auriez besoin
de sauvegarder les cls prives dans le service de chiffrement, il vous suffira de crer une instance de
la classe CspParameters en oubliant pas de spcifier un nom de conteneur (via la proprit
KeyContainerName),
de passer votre objet dans le constructeur de la classe
RSACryptoServiceProvider et de placer la proprit PersistKeyInCsp True :

Date

65

La scurit du .NET Framework

VB
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Dim taillecle As Integer
Dim chemin_fichier As String
Dim _clepublic, _cleprivee As RSAParameters
Sub Main()
taillecle = 384
chemin_fichier = "C:\test.bin"
Destinataire()
FournisseurDeDonnees(_clepublic)
Destinataire(_cleprivee)
Console.Read()
End Sub
'Mthode gnrant les cls prives et publiques
Public Sub Destinataire()
Dim keygen As RSACryptoServiceProvider = New
RSACryptoServiceProvider(taillecle)
_clepublic = keygen.ExportParameters(False)
_cleprivee = keygen.ExportParameters(True)
Console.WriteLine("Destinataire a gnr les cls suivantes:" +
vbNewLine + "Cle prive: " + keygen.ToXmlString(True) + vbNewLine +
vbNewLine + "Cle publique: " + keygen.ToXmlString(False) + vbNewLine)
keygen.Clear()
End Sub
'Mthode de dcryptage des donnes l'aide de la cl prive
Public Sub Destinataire(ByVal cleprivee As RSAParameters)
Dim fichier As FileStream = New FileStream(chemin_fichier,
FileMode.Open)
Dim octets(fichier.Length - 1) As Byte
fichier.Read(octets, 0, fichier.Length)
fichier.Close()
Console.WriteLine("Texte avant dcryptage: {0}",
Encoding.Unicode.GetString(octets))
Dim decrypt As RSACryptoServiceProvider = New
RSACryptoServiceProvider(taillecle)
decrypt.ImportParameters(cleprivee)
Dim finaltxt As StringBuilder = New StringBuilder()
Dim o() As Byte = decrypt.Decrypt(octets, False)
Console.WriteLine("Texte aprs dcryptage: {0}",
Encoding.Unicode.GetString(o))
End Sub

Date

66

La scurit du .NET Framework

VB - Suite
'Mthode cryptant les donnes en utilisant la cl publique
Public Sub FournisseurDeDonnees(ByVal clepublic As RSAParameters)
Dim encryptor As RSACryptoServiceProvider = New
RSACryptoServiceProvider(taillecle)
encryptor.ImportParameters(clepublic)
Console.WriteLine("Fournisseur de donnes." + vbNewLine + "Cle
prive disponible?" + (Not encryptor.PublicOnly).ToString() + vbNewLine)
Dim fichier As FileStream = New FileStream(chemin_fichier,
FileMode.Truncate)
Dim o() As Byte =
encryptor.Encrypt(Encoding.Unicode.GetBytes("Donnees."), False)
For Each b As Byte In o
fichier.WriteByte(b)
Next
fichier.Flush()
fichier.Close()
encryptor.Clear()
End Sub

Date

67

La scurit du .NET Framework

//C#
using System.Security.Cryptography
using System.IO
using System.Text
private static int taillecle;
private static string chemin_fichier;
private static RSAParameters _clepublic;
private static RSAParameters _cleprivee;
static void Main(string[] args)
{
taillecle = 384;
chemin_fichier = @"C:\test.bin";
Destinataire();
FournisseurDeDonnees(_clepublic);
Destinataire(_cleprivee);
Console.Read();
}
//Mthode gnrant les cls prives et publiques
public static void Destinataire()
{
RSACryptoServiceProvider keygen = new
RSACryptoServiceProvider(taillecle);
_clepublic = keygen.ExportParameters(false);
_cleprivee = keygen.ExportParameters(true);
Console.WriteLine("Destinataire a gnr les cls suivantes:\n" +
"Cle prive: " + keygen.ToXmlString(true) + "\n\n"
+
"Cle publique: " + keygen.ToXmlString(false) +
"\n");
keygen.Clear();
}

//Mthode de dcryptage des donnes l'aide de la cl prive


public static void Destinataire(RSAParameters cleprivee)
{
FileStream fichier = new FileStream(chemin_fichier, FileMode.Open);
byte[] octets = new byte[fichier.Length];
fichier.Read(octets, 0, (int)fichier.Length);
fichier.Close();
Console.WriteLine("Texte avant dcryptage: {0}",
Encoding.Unicode.GetString(octets));
RSACryptoServiceProvider decrypt = new
RSACryptoServiceProvider(taillecle);
decrypt.ImportParameters(cleprivee);

StringBuilder finaltxt = new StringBuilder();


byte[] o = decrypt.Decrypt(octets, false);
Console.WriteLine("Texte aprs dcryptage: {0}",
Encoding.Unicode.GetString(o));
}

Date

68

La scurit du .NET Framework

//C# - Suite
//Mthode cryptant les donnes en utilisant la cl publique
public static void FournisseurDeDonnees(RSAParameters clepublic)
{
//Cr l'outil d'encryption des donnes
RSACryptoServiceProvider encryptor = new
RSACryptoServiceProvider(taillecle);
encryptor.ImportParameters(clepublic);
Console.WriteLine("Fournisseur de donnes.\n" + "Cle prive
disponible?" + (!encryptor.PublicOnly).ToString() + "\n");
//Ecrit les donnes cryptes dans le fichier
FileStream fichier = new FileStream(chemin_fichier,
FileMode.Truncate);
byte[] o = encryptor.Encrypt(Encoding.Unicode.GetBytes("Donnees."),
false);
foreach(byte b in o)
fichier.WriteByte(b);
fichier.Flush();
fichier.Close();
encryptor.Clear();
}

Pour excuter correctement ce programme, vous devrez d'abord crer le fichier C:\test.bin.
Lorsque vous excutez ce programme, vous devriez obtenir quelque chose de similaire a
dans la console :
Destinataire a gnr les cls suivantes:
Cle prive: <RSAKeyValue><Modulus>0H4COsdum97UQNSM0cZehGDaMrXA7rMYb3RhJGdDmvKHID
NNpnSEOtULcHDmN8AF</Modulus><Exponent>AQAB</Exponent><P>7+me3vc7g479qh6bhEMpdipt
lD0KGCqj</P><Q>3nkFX8qU2EDrZPIk3PDXIkXXdoopR303</Q><DP>AJjBJ2bQBBS/9sNauap9GOkkG
qFIPCUn</DP><DQ>z837Vx7DKbx6JDCKflX4nere97rWFBDB</DQ><InverseQ>GaotrImHs4dXSjz0A
1/V/yKTYT1JnqYn</InverseQ><D>m7vT/IXlaAaM8xQRT8xl42nY8pHy2BnrqEpwl/T63ckE2vW9ImJ
rMQ0naN7WWTXN</D></RSAKeyValue>
Cle publique: <RSAKeyValue><Modulus>0H4COsdum97UQNSM0cZehGDaMrXA7rMYb3RhJGdDmvKH
IDNNpnSEOtULcHDmN8AF</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
Fournisseur de donnes.
Cle prive disponible?False
Texte avant dcryptage: ????????????????????????
Texte aprs dcryptage: Donnees.

Date

69

La scurit du .NET Framework

Si vous ouvrez le fichier C:\test.bin, vous devriez avoir un texte totalement incomprhensible :

Afin de dterminer quelle(s) cl(s) sera exporte(s) lors de l'appel une mthode
d'exportation, vous pouvez en gnral passer en argument un boolen indiquant :
True : la cl prive sera exporte en plus de la cl publique.
False : Seule la cl publique sera exporte.
Lorsque vous appelez une des mthodes de cryptage ou de dcryptage, vous devez spcifier
deux paramtres :
Un tableau d'octets contenant les donnes crypter.
Un boolen indiquant si le service de chiffrement utilisera PKCS#1 v1.5
(essentiellement pour des soucis de rtrocompatibilits puisque disponible depuis plus
longtemps, il est dconseill de nos jours car il prsente de nombreuses faiblesses) ou
OAEP (disponible uniquement sur des machines XP ou plus rcentes).
Vous aurez constat que dans la cl prive au format XML, plusieurs balises sont cres.
Chacune de ces balises reprsentent une partie des donnes permettant de gnrer les cls utilises
(pour savoir de quelle faon sont gnres les cls, je vous renvoi vers le lien concernant l'algorithme
RSA. Sachez juste ventuellement que "Modulus" est le module de chiffrement n et "Exponent" est
l'exposant de chiffrement e).
6.3.2

DSACryptoServiceProvider
Cette classe vous donne accs aux algorithmes de calcul DSA. Elle possde les mmes
membres que RSACryptoServiceProvider mais ne dispose pas des mthodes Encrypt et
Decrypt. Du fait de l'absence de ces deux mthodes, le cryptage DSA ne peut pas tre utilis
directement pour crypter des donnes. En revanche, il peut tre d'une grande utilit si vous
souhaitez implmenter un service fournissant des signatures, des cls publiques/prives et/ou des
empreintes digitales de donnes.

Date

70

La scurit du .NET Framework

6.4 Signatures numriques


Les signatures numriques permettent dapposer un document numrique une signature
prouvant que le document vient bien de vous. Cela permet de vrifier la provenance dun document
et ainsi dtre sr den dtenir la bonne copie. Les signatures peuvent tre vrifies grce une cl
publique fournit avec le document.
Les deux classes de chiffrements asymtriques vous permettent de signer les donnes grce
leurs mthodes SignData, SignHash, VerifyData et VerifyHash.
Vous allez devoir, dans vos codes, utiliser conjointement SignData avec VerifyData ou
SignHash avec VerifyHash. Nous allons illustrer lutilisation des mthodes SignData et
VerifyData de la classe RSACryptoServiceProvider en guise dexemple. Sachez que
lutilisation de DSACryptoService est quasi-identique, de mme que lutilisation des deux autres
mthodes.

Date

71

La scurit du .NET Framework

'VB
Imports System.Security.Cryptography
Imports System.IO
Sub Main()
'(1)
Dim RSA As RSACryptoServiceProvider = New
RSACryptoServiceProvider()
Dim clepublique As String = ""
Dim signatureNumerique() As Byte
'(2)
signatureNumerique = Signature(RSA, clepublique)
Console.WriteLine("La signature est : {0}",
Convert.ToBase64String(signatureNumerique))
'(3)
Verification(RSA, signatureNumerique, clepublique)
Console.Read()
End Sub
Public Function Signature(ByRef provider As RSACryptoServiceProvider,
ByRef clepublique As String) As Byte()
'(4)
Dim flux As FileStream = New FileStream("C:\test.txt",
FileMode.Open, FileAccess.Read)
Dim lecteur As BinaryReader = New BinaryReader(flux)
'(5)
Dim donnees() As Byte = lecteur.ReadBytes(CType(flux.Length,
Integer))
lecteur.Close()
flux.Close()
'(6)
clepublique = provider.ToXmlString(False)
'(7)
Return provider.SignData(donnees, New
SHA1CryptoServiceProvider())
End Function
Public Sub Verification(ByRef provider As RSACryptoServiceProvider, ByVal
signature() As Byte, ByRef clefpublique As String)
'(8)
provider.FromXmlString(clefpublique)
Dim flux As FileStream = New FileStream("C:\test.txt",
FileMode.Open, FileAccess.Read)
Dim lecteur As BinaryReader = New BinaryReader(flux)
'(9)
Dim donnees() As Byte = lecteur.ReadBytes(CType(flux.Length,
Integer))
lecteur.Close()
flux.Close()
'(10)
If (provider.VerifyData(donnees, New SHA1CryptoServiceProvider(),
signature)) Then
Console.WriteLine("La signature est vrifie")
Else
Console.WriteLine("La signature est mauvaise")
End If
End Sub

Date

72

La scurit du .NET Framework

//C#
using System.Security.Cryptography;
using System.IO;
public static void Main(string[] args)
{
//(1)
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string clepublique = "";
byte[] signatureNumerique = null;
//(2)
signatureNumerique = Signature(ref RSA, ref clepublique);
Console.WriteLine("La signature est : {0}",
Convert.ToBase64String(signatureNumerique));
//(3)
Verification(ref RSA, signatureNumerique, ref clepublique);
Console.Read();
}
public static byte[] Signature(ref RSACryptoServiceProvider provider, ref
string clepublique)
{
//(4)
FileStream flux = new FileStream(@"C:\test.txt", FileMode.Open,
FileAccess.Read);
BinaryReader lecteur = new BinaryReader(flux);
//(5)
byte[] donnees = lecteur.ReadBytes((int)flux.Length);
lecteur.Close();
flux.Close();
//(6)
clepublique = provider.ToXmlString(false);
//(7)
return provider.SignData(donnees, new SHA1CryptoServiceProvider());
}
public static void Verification(ref RSACryptoServiceProvider provider,
byte[] signature, ref string clefpublique)
{
//(8)
provider.FromXmlString(clefpublique);
FileStream flux = new FileStream(@"C:\test.txt", FileMode.Open,
FileAccess.Read);
BinaryReader lecteur = new BinaryReader(flux);
//(9)
byte[] donnees = lecteur.ReadBytes((int)flux.Length);
lecteur.Close();
flux.Close();
//(10)
if (provider.VerifyData(donnees, new SHA1CryptoServiceProvider(),
signature))
Console.WriteLine("La signature est vrifie");
else
Console.WriteLine("La signature est mauvaise");
}

Date

73

La scurit du .NET Framework

Pour plus de clart nous avons plac des numros dans le code permettant de commenter
chaque partie.
1) Nous instancions un objet RSACryptoServiceProvider qui va nous permettre de signer et
vrifier la signature.
2) Nous appelons la mthode Signature, rcuprons sa valeur de retour puis nous laffichons. La
mthode Signature signe un fichier retourne la signature et passe par rfrence la valeur de
clepublique.
3) Nous appelons la mthode Verification qui va se charger de vrifier la signature du fichier.
4) On cre deux flux, un flux sur un fichier, et un BinaryReader utilisant le flux de fichier.
5) On lit entirement le fichier et on remplit un tableau doctets avec les informations
recueillies
6) On rcupre la cl publique sous forme XML (ici rang dans une chane de caractre)
7) On signe le fichier partir de son contenu (donnees) et avec un hash en SHA1, on retourne la
signature.
8) On rcupre la cl publique sous forme XML.
9) On lit le contenu du fichier et le range dans des tableaux doctets (mme tape que 5)
10) On vrifie la signature. A partir du contenu du fichier que lon hash grce SHA1 on cre une
nouvelle signature que l'on compare celle passe en troisime paramtre.
Voici ce qui ressort dans la console. Bien entendu la signature est diffrente d'un fichier un autre :
La signature est : LCgTxY3XYOPB3rTTLzT6dBas3x7lpwaaA2/HHaJNvcUgcHXe+EMhWKetUm9xT
v37X1+wv5PUI7Jh8KXwZ2POoHYFr3vhKFsvG31PcGCoyYKrjCkBJ9kDzdttdgAMo67xvAXl1Fxry1Vqh
9VxyT7Xvw4GPfhS96u2R0/mc3ncsBs=
La signature est vrifie

Date

74

La scurit du .NET Framework

7 Conclusion
Vous voil donc quip en matire de scurit en ce qui concerne le Framework .NET. Vous
savez dsormais comment fonctionne les rgles de scurit de la CLR et quels sont les moyens pour
prvenir les exploits de vos applications ou encore le piratage de donnes sauvegardes.
A la fin de ce chapitre, vous devriez:
Savoir comment fonctionne le CAS du Framework .NET et comment le configurer.
Avoir compris comment fonctionnent les rgles de scurit par rapport au systme
d'exploitation hte qui excutera l'assembly.
Savoir comment effectuer des demandes d'autorisations, comment en refuser que a
soit dans le code (au dessus des mthodes/classes) ou au niveau de l'assembly toute
entire.
Savoir comment grer les ACLs (Discrtionnaire ou de scurit) du systme
d'exploitation partir du code.
Connaitre les diffrentes techniques possibles pour chiffrer des donnes afin de les
protger lors de transfert ou pour les stocker long terme sur un mdia (disque dur,
cd-rom)

N'oubliez pas que la librairie MSDN peut vous tre d'une aide prcieuse pour vos
dveloppements :

Date