Ce sujet n'a pas encore été évalué - Évaluez ce sujet

Procédure : création d'une autorisation de cryptage personnalisée

Dernière mise à jour le 31 août 2004
Sur cette page

Objectifs Objectifs
S'applique à S'applique à
Résumé Résumé
À savoir avant de commencer À savoir avant de commencer
Création de la classe EncryptionPermission Création de la classe EncryptionPermission
Création de la classe EncryptionPermissionAttribute Création de la classe EncryptionPermissionAttribute
Installation de l'assembly d'autorisation dans le GAC Installation de l'assembly d'autorisation dans le GAC
Mise à jour du code wrapper géré DPAPI Mise à jour du code wrapper géré DPAPI
Appel de DPAPI à partir d'une application Web moyennement sécurisée Appel de DPAPI à partir d'une application Web moyennement sécurisée

Objectifs

Ce module vous permettra d'effectuer les opérations suivantes :

  • développer, implémenter et utiliser une autorisation CAS personnalisée ;

  • utiliser l'autorisation d'accès au code personnalisée pour contrôler l'accès aux fonctionnalités de cryptage non géré fournies par DPAPI.

S'applique à

Ce module s'applique aux produits et technologies suivants :

  • Microsoft® Windows® 2000 Server et Windows 2000 Professionnel, Windows Server? 2003, Windows XP Édition Professionnel ;

  • Internet Information Server (IIS) ;

  • .NET Framework 1.1.

Résumé

Les capacités de sécurité d'accès au code (CAS) de .NET Framework sont extensibles. Vous pouvez ainsi implémenter vos propres autorisations pour contrôler l'accès aux fonctionnalités personnalisées importantes.

Ce module indique comment créer une autorisation CAS personnalisée pour contrôler l'accès par programme au code wrapper DPAPI (Data Protection API) géré. Ce code est décrit dans l'article « How to: Create a DPAPI Library » de MSDN Library à l'adresse : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT07.asp.

À savoir avant de commencer

Les autorisations de sécurité d'accès au code doivent être dérivées de System.Security.CodeAccessPermission, qui fournit une implémentation de la méthode Demand définie par l'interface IPermission, en même temps que d'autres tels que Assert, Deny et PermitOnly, qui sont définies par l'interface IStackWalk.

Les autorisations d'accès au code (et non les autorisations d'identité) implémentent également l'interface IUnrestrictedPermission, pour indiquer que l'autorisation fait partie du jeu d'autorisations illimitées. Cela signifie que l'autorisation est automatiquement accordée à n'importe quel code bénéficiant d'une confiance totale. La hiérarchie d'héritage de l'autorisation personnalisée EncryptionPermission implémentée dans ce module apparaît dans la figure 1.

Hiérarchie d'héritage de l'autorisation personnalisée EncryptionPermission

Figure 1
Hiérarchie d'héritage de l'autorisation personnalisée EncryptionPermission

La classe personnalisée EncryptionPermission gère les états suivants :

  • EncryptionPermissionFlag. Détermine si le code qui bénéficie de cette autorisation peut crypter les données, les décrypter ou les deux.

  • StorePermissionFlag. Détermine si le code qui bénéficie de cette autorisation peut utiliser DPAPI avec le magasin de l'ordinateur, le magasin d'utilisateurs actuels ou les deux.

Création de la classe EncryptionPermission

La classe EncryptionPermission est l'implémentation d'autorisation personnalisée permettant d'autoriser l'accès à la fonctionnalité DPAPI non gérée.

  • Pour créer la classe CustomPermission

    1. Créez un nouveau projet Bibliothèque de classes CustomPermission avec l'outil de développement Visual C#TM et renommez class1.cs en EncryptionPermission.cs.

    2. Ajoutez un nom fort à l'assembly pour pouvoir l'installer dans le GAC. Utilisez l'attribut suivant dans assemblyinfo.cs :

      [assembly: AssemblyKeyFile(@"..\..\CustomPermissions.snk")]
      
    3. Utilisez une version d'assembly fixe.

      [assembly: AssemblyVersion("1.0.0.1")]
      
    4. Ajoutez l'instruction using suivante en haut de EncryptionPermission.cs.

      using System.Security;
      using System.Security.Permissions;
      
    5. Ajoutez les types énumérés suivants à l'espace de noms CustomPermissions.

      [Flags, Serializable]
      public enum EncryptionPermissionFlag
      {Encrypt = 0x01, Decrypt = 0x02}
      
      [Flags, Serializable]
      public enum StorePermissionFlag
      {User = 0x01, Machine = 0x02}
      
    6. Ajoutez la prise en charge de la sérialisation à la classe EncryptionPermission avec l'attribut [Serializable], et dérivez-le de CodeAccessSecurity et IUnrestrictedPermission. Scellez également la classe, comme indiqué ci-dessous.

      [Serializable]
      public sealed class EncryptionPermission : CodeAccessPermission, 
                                                 IUnrestrictedPermission
      
    7. Ajoutez deux variables membres privées pour maintenir l'état d'autorisation.

      private EncryptionPermissionFlag _permFlag;
      private StorePermissionFlag _storePermFlag;
      
    8. Remplacez le constructeur par défaut par les constructeurs suivants.

      // Par convention, les types d'autorisations fournissent un constructeur 
      // qui accepte l'énumération PermissionState.
      public EncryptionPermission(PermissionState state)
      {
        if (state.Equals(PermissionState.Unrestricted))
        {
          _permFlag = EncryptionPermissionFlag.Encrypt | 
                      EncryptionPermissionFlag.Decrypt;
          _storePermFlag = StorePermissionFlag.User | StorePermissionFlag.Machine;
        }
        else
        {
          _permFlag &= ~(EncryptionPermissionFlag.Encrypt | 
                         EncryptionPermissionFlag.Decrypt);
          _storePermFlag &= ~(StorePermissionFlag.User | 
                              StorePermissionFlag.Machine);
        }
      }
      // Ce constructeur vous permet de spécifier le type de cryptage (cryptage
      // ou décryptage) à l'aide de l'énumération EncryptionPermissionFlag et de la base de clés DPAPI
      //  à utiliser (utilisateur ou machine) comme indiqué par l'énumération 
      // StorePermissionFlag.
      public EncryptionPermission(EncryptionPermissionFlag cipher, 
                                  StorePermissionFlag store)
      {
        _permFlag = cipher;
        _storePermFlag = store;
      }
      public EncryptionPermission()
      {
        _permFlag &= ~EncryptionPermissionFlag.Encrypt | 
                      EncryptionPermissionFlag.Decrypt;
        _storePermFlag &= ~(StorePermissionFlag.User | StorePermissionFlag.Machine);
      }
      
    9. Ajoutez les propriétés publiques suivantes pour permettre à une application client de définir l'état de la classe d'autorisation.

      							
      // Définir cette propriété sur true pour autoriser le cryptage.
      public bool Encrypt
      {
        set {
          if(true == value)
          {
            _permFlag |= EncryptionPermissionFlag.Encrypt;
          }
          else
          {
            _permFlag &= ~EncryptionPermissionFlag.Encrypt;
          }
        }            
        get {
          return (_permFlag & EncryptionPermissionFlag.Encrypt).Equals(
                              EncryptionPermissionFlag.Encrypt);
        }
      }
      
      // Définir cette propriété sur true pour autoriser le décryptage.
      public bool Decrypt
      {
        set {
          if(true == value)
          {
            _permFlag |= EncryptionPermissionFlag.Decrypt;
          }
          else
          {
            _permFlag &= ~EncryptionPermissionFlag.Decrypt;
          }
        }
        get {
          return (_permFlag & EncryptionPermissionFlag.Decrypt).Equals(
                              EncryptionPermissionFlag.Decrypt);
        }
      }
      // Définir cette propriété sur true pour employer la clé machine DPAPI.
      public bool MachineStore
      {
        set {
          if(true == value)
          {
            _storePermFlag |= StorePermissionFlag.Machine;
          }
          else
          {
            _storePermFlag &= ~StorePermissionFlag.Machine;
          }
        }            
        get {
          return (_storePermFlag & StorePermissionFlag.Machine).Equals(
                                   StorePermissionFlag.Machine);
        }
      }
      // Définir cette propriété sur true pour employer la clé utilisateur DPAPI.<
      public bool UserStore
      {
        set {
          if(true == value)
          {
            _storePermFlag |= StorePermissionFlag.User;
          }
          else
          {
            _storePermFlag &= ~StorePermissionFlag.User;
          }
        }
        get {
          return (_storePermFlag & StorePermissionFlag.User).Equals(
                                   StorePermissionFlag.User);
        }
      }
      
    10. Implémentez IPermission.Copy. Une copie identique de l'instance d'autorisation actuelle est créée et renvoyée à l'appelant.

      public override IPermission Copy()
      {
        return  new EncryptionPermission(_permFlag, _storePermFlag);
      }
      
    11. Implémentez IPermission.Intersect. L'objet d'autorisation renvoyé est le résultat de l'intersection entre l'autorisation actuelle et l'autorisation fournie.

      public override IPermission Intersect(IPermission target)
      {
        // Une entrée nulle indique une autorisation sans état.
        // Il ne peut pas y avoir d'état commun, donc la méthode renvoie une valeur nulle.
        if (target == null)
          return null;
      
        if (!(target.GetType().Equals(this.GetType())))
          throw new ArgumentException(
                        "L'argument doit être de type EncryptionPermission.");
      
        // Convertir la cible en EncryptionPermission.
        EncryptionPermission targetPerm = (EncryptionPermission)target;
      
        EncryptionPermissionFlag intersectEncryption = this._permFlag & 
                                                       targetPerm._permFlag;
        StorePermissionFlag intersectStore = this._storePermFlag &
                                             targetPerm._storePermFlag;
      
        return new EncryptionPermission(intersectEncryption, intersectStore);
      }
      
    12. Implémentez IPermission.Union. L'objet d'autorisation renvoyé est le résultat de l'union entre l'autorisation actuelle et l'autorisation fournie.

      public override IPermission Union(IPermission target)
      {
        if (target == null)
          return Copy();
      
        if (!(target.GetType().Equals(this.GetType())))
          throw new ArgumentException(
                             "L'argument doit être de type EncryptionPermission.");
      
        // Convertir la cible en EncryptionPermission.
        EncryptionPermission targetPerm = (EncryptionPermission)target;
      
        EncryptionPermissionFlag unionEncryption = this._permFlag | 
                                                   targetPerm._permFlag;
        StorePermissionFlag unionStore = this._storePermFlag | 
                                          targetPerm._storePermFlag;
      
        return new EncryptionPermission(unionEncryption, unionStore);
      }
      
    13. Implémentez IPermission.IsSubsetOf. Cette méthode renvoie un bool pour indiquer si l'autorisation actuelle est un sous-ensemble de l'autorisation fournie ou non. Pour être un sous-ensemble, chaque élément d'état de l'autorisation actuelle doit également être dans l'autorisation cible.

      public override bool IsSubsetOf(IPermission target)
      {
        // Une entrée nulle indique une autorisation sans état.
        // L'autorisation ne peut être qu'un sous-ensemble si elle se trouve dans un état vide similaire.
        bool canEncrypt, canDecrypt;
        bool canUseMachineStore, canUseUserStore;
      
        bool canTargetEncrypt, canTargetDecrypt;
        bool canTargetUseMachineStore, canTargetUseUserStore;
      
        canEncrypt = (this._permFlag & 
                      EncryptionPermissionFlag.Encrypt).
                      Equals(EncryptionPermissionFlag.Encrypt);
        canDecrypt = (this._permFlag & 
                      EncryptionPermissionFlag.Decrypt).
                      Equals(EncryptionPermissionFlag.Decrypt);
        canUseMachineStore = (this._storePermFlag & 
                              StorePermissionFlag.Machine).
                              Equals(StorePermissionFlag.Machine);
        canUseUserStore = (this._storePermFlag & 
                           StorePermissionFlag.User).
                           Equals(StorePermissionFlag.User);
      
        if (target == null)
        {
          if ((canEncrypt == false && canDecrypt == false) && (canUseMachineStore == 
               false  && canUseUserStore == false))
            return true;
          else
            return false;
        }
      
        if (!(target.GetType().Equals(this.GetType())))
          throw new ArgumentException(
                                 "L'argument doit être de type EncryptionPermission.");
      
        // Convertir la cible en EncryptionPermission.
        EncryptionPermission targetPerm = (EncryptionPermission)target;
      
        canTargetEncrypt = (targetPerm._permFlag & 
                            EncryptionPermissionFlag.Encrypt).
                            Equals(EncryptionPermissionFlag.Encrypt);
        canTargetDecrypt = (targetPerm._permFlag &  
                            EncryptionPermissionFlag.Decrypt).
                            Equals(EncryptionPermissionFlag.Decrypt);
      
        canTargetUseMachineStore = (targetPerm._storePermFlag & 
                                    StorePermissionFlag.Machine).
                                    Equals(StorePermissionFlag.Machine);
        canTargetUseUserStore = (targetPerm._storePermFlag & 
                                 StorePermissionFlag.User).
                                 Equals(StorePermissionFlag.User);
      
        // Chaque jeu de valeurs (true) contenu dans cette autorisation doit figurer dans la cible.
        // Le code suivant contrôle si l'autorisation en cours est un sous-ensemble 
        // de la cible. Si l'autorisation en cours contient quelque chose que la cible 
        // ne contient pas, il ne peut pas s'agir d'un sous-ensemble.
        if(canEncrypt == true && canTargetEncrypt == false)
          return false;
        if(canDecrypt == true && canTargetDecrypt == false)
          return false;
        if(canUseMachineStore == true && canTargetUseMachineStore == false)
          return false;
        if(canUseUserStore == true && canTargetUseUserStore == false)
          return false;
      
        return true;
      }
      
    14. Implémentez ISecurityEncodable.ToXml et FromXml. Ces méthodes convertissent les instances d'un objet d'autorisation au format XML et vice-versa. Elles sont utilisées pour prendre en charge la sérialisation. Celle-ci est utilisée, par exemple, lorsque l'attribut de sécurité est stocké dans les métadonnées de l'assembly.

      public override SecurityElement ToXml()
      {
        // Créer un nouvel élément. Le nom de la balise doit toujours être IPermission.
        SecurityElement elem = new SecurityElement("IPermission");
      
        // Déterminer le nom de type complet (incluant le nom d'assembly) de
        // la classe EncryptionPermission (Le système de sécurité emploie ce nom pour
        // localiser et charger la classe.)
        string name = typeof(EncryptionPermission).AssemblyQualifiedName;
      
        // Ajouter les attributs pour le nom de classe et la version de protocole.
        // La version doit être 1 actuellement.
        elem.AddAttribute("class", name);
        elem.AddAttribute("version", "1" );
      
        if (IsUnrestricted())
        {
          // L'utilisation de l'attribut Unrestricted est conforme aux
          // types d'autorisations intégrés de .NET Framework et vous aide à 
          // garder un cryptage compact.
          elem.AddAttribute("Unrestricted", Boolean.TrueString);
        }
        else
        {
          // Coder chaque champ d'état sous forme d'attribut de l'élément Permission.
          // Pour le compactage, coder uniquement les paramètres d'état qui ne sont pas des paramètres par défaut.
          elem.AddAttribute("Flags", this._permFlag.ToString());
          elem.AddAttribute("Stores", this._storePermFlag.ToString());
        }
        // Renvoyer l'élément terminé.
        return elem;
      }
      
      // Convertit un élément SecurityElement (ou un arbre d'éléments) en instance
      // d'autorisation.
      public override void FromXml(SecurityElement elem)
      {
        string attrVal = "";
        // Rechercher une instance illimitée.
        attrVal = elem.Attribute("Unrestricted");
        if (attrVal != null)
        {
          if(attrVal.ToLower().Equals("true"))
          { 
            this._permFlag = EncryptionPermissionFlag.Encrypt | 
                             EncryptionPermissionFlag.Decrypt;
            this._storePermFlag = StorePermissionFlag.Machine | 
                                  StorePermissionFlag.User;
          }
          return;
        }
      
        //Désactiver les indicateurs d'autorisation et de stockage.
        this._permFlag &= ~(EncryptionPermissionFlag.Encrypt | 
                            EncryptionPermissionFlag.Decrypt);
        this._storePermFlag &= ~(StorePermissionFlag.Machine | 
                                 StorePermissionFlag.User);
      
        attrVal = elem.Attribute("Flags");
        if (attrVal != null)
        {
          if(!attrVal.Trim().Equals(""))
          {
            this._permFlag = 
             (EncryptionPermissionFlag)Enum.Parse(typeof(EncryptionPermissionFlag),
                                                         attrVal);
          }
        }
      
        attrVal = elem.Attribute("Stores");
        if (attrVal != null)
        {
          if(!attrVal.Trim().Equals(""))
          {
            this._storePermFlag = 
                        (StorePermissionFlag)Enum.Parse(typeof(StorePermissionFlag), 
                                                               attrVal);
          }
        }
      }
      
    15. Implémentez IUnrestrictedPermission.IsUnrestricted. Cette méthode renvoie TRUE si l'état de l'instance d'autorisation est non restreint. Dans ce cas, une instance EncryptionPermission non restreinte permet au code de crypter et de décrypter les données à l'aide des magasins d'ordinateurs et d'utilisateurs DPAPI.

      public bool IsUnrestricted()
      {
        bool canEncrypt, canDecrypt, canUseUserStore, canUseMachineStore;
        canEncrypt = (this._permFlag & 
                      EncryptionPermissionFlag.Encrypt).
                      Equals(EncryptionPermissionFlag.Encrypt);
        canDecrypt = (this._permFlag & 
                      EncryptionPermissionFlag.Decrypt).
                      Equals(EncryptionPermissionFlag.Decrypt);
        canUseUserStore = (this._storePermFlag & 
                           StorePermissionFlag.User).
                           Equals(StorePermissionFlag.User);
        canUseMachineStore = (this._storePermFlag & 
                              StorePermissionFlag.Machine).
                              Equals(StorePermissionFlag.Machine);
        return ((canEncrypt && canDecrypt) && 
                (canUseUserStore && canUseMachineStore));
      }
      

Création de la classe EncryptionPermissionAttribute

.NET Framework utilise des classes d'attributs qui sont associées à leurs classes d'autorisations partenaires pour coder les instances d'autorisation. Des attributs d'autorisation sont nécessaires pour prendre en charge la syntaxe de sécurité déclarative.

  • Pour créer la classe EncryptionPermissionAttribute

    1. Ajoutez un nouveau fichier de classe au projet en cours, EncryptionPermissionAttribute.cs.

    2. Ajoutez l'instruction using suivante en haut du nouveau fichier.

      using System.Security;
      using System.Diagnostics;
      using System.Security.Permissions;
      
    3. Dérivez la classe d'attribut de CodeAccessSecurityAttribute et scellez-la.

      public sealed class EncryptionPermissionAttribute : 
                                           CodeAccessSecurityAttribute
      
    4. Ajoutez une prise en charge de la sérialisation à la classe et utilisez l'attribut AttributeUsage pour indiquer où utiliser l'attribut d'autorisation personnalisée.

      [Serializable, 
      AttributeUsage(AttributeTargets.Method |      // Peut être utilisé sur des méthodes
                     AttributeTargets.Constructor | // Peut être utilisé sur des constructeurs
                     AttributeTargets.Class |       // Peut être utilisé sur des classes
                     AttributeTargets.Struct |      // Peut être utilisé sur des structures
                     AttributeTargets.Assembly,     // Peut être utilisé au niveau assembly
                     AllowMultiple = true,          // Peut utiliser plusieurs instances
                                                    // d'attribut par élément de programme 
                                                    // (classe, méthode, etc.)
                     Inherited = false)]            // Ne peut pas être hérité
      
    5. Ajoutez des variables membres privées à la classe pour faire une copie miroir de l'état maintenu par la classe d'autorisation associée.

      // Les champs d'état suivants reflètent ceux qui sont utilisés dans le type 
      // d'autorisation associé.
      private bool _encrypt = false;
      private bool _decrypt = false;
      private bool _machineStore = false;
      private bool _userStore = false;
      
    6. Remplacez le constructeur par défaut par le constructeur suivant.

      // Renvoyer le code d'action à la classe de base.
      public EncryptionPermissionAttribute(SecurityAction action) : base(action)
      {
      }
      
    7. Ajoutez les propriétés publiques suivantes pour effectuer une copie miroir de celles fournies par la classe d'autorisation associée.

      public bool Encrypt
      {
        get {
          return _encrypt;
        }
        set {
          _encrypt = value;
        }
      }
      public bool Decrypt
      {
        get {
          return _decrypt;
        }
        set {
          _decrypt = value;
        }
      }
      public bool UserStore
      {
        get {
          return _userStore;
        }
        set {
          _userStore = value;
        }
      }
      public bool MachineStore
      {
        get {
          return _machineStore;
        }
        set {
          _machineStore = value;
        }
      }
      
    8. Implémentez SecurityPermissionAttribute.CreatePermission. Cette méthode crée un objet d'autorisation qui peut ensuite être sérialisé et rendu persistant en spécifiant l'énumération SecurityAction dans les métadonnées d'un assembly.

      public override IPermission CreatePermission()
      {
        // L'exécution fournit automatiquement une propriété pour indiquer
        // si une instance illimitée est requise ou non.
        if((Unrestricted) || ((_encrypt && _decrypt) && 
                              (_userStore && _machineStore)))
        {
          return new EncryptionPermission(PermissionState.Unrestricted);
        }
      
        // Copier l'état de l'attribut à l'objet autorisation
        EncryptionPermissionFlag cipher = 0x0;
        StorePermissionFlag store = 0x0;
      
        if(_encrypt)
          cipher |= EncryptionPermissionFlag.Encrypt;
      
        if(_decrypt)
          cipher |= EncryptionPermissionFlag.Decrypt;
      
        if(_userStore)
          store |= StorePermissionFlag.User;
      
        if(_machineStore)
          store |= StorePermissionFlag.Machine;
      
        // Renvoyer l'autorisation finale.
        return new EncryptionPermission(cipher, store);
      }
      
    9. Générez la solution.

Installation de l'assembly d'autorisation dans le GAC

Vous devez accorder une confiance totale à tout assembly implémentant une autorisation de sécurité personnalisée. En pratique, cela signifie que vous devez installer l'assembly sur l'ordinateur où il est utilisé, pour vous assurer qu'il bénéficie d'une confiance totale attribuée par la stratégie de sécurité par défaut. Le code de My_Computer_Zone bénéficie d'une confiance totale attribuée par la stratégie par défaut.

L'installation d'un assembly dans le GAC est un moyen de s'assurer qu'il bénéficie d'une confiance totale attribuée par la stratégie de sécurité d'accès au code. Le GAC est un emplacement approprié pour l'assembly d'autorisation parce que l'assembly est utilisé par la stratégie de sécurité d'accès au code sur l'ordinateur local et est disponible pour n'importe quelle application .NET Framework installée sur l'ordinateur local.

Pour installer l'assembly d'autorisation personnalisée dans le GAC de l'ordinateur local, exécutez la commande suivante.

gacutil.exe /i custompermission.dll

Mise à jour du code wrapper géré DPAPI

La fonctionnalité DPAPI n'est pas actuellement exposée par la bibliothèque de classes .NET Framework. Pour appeler DPAPI à partir d'une application .NET Framework, vous devez utiliser P/Invoke. Pour des informations sur le code permettant de créer un assembly wrapper DPAPI géré, consultez l'article « Procédure : création d'une bibliothèque DPAPI ».

Sans autre modification, vous pouvez uniquement appeler le wrapper DPAPI géré de l'article de procédure référencé à partir du code de confiance totale. Pour appeler le wrapper DPAPI à partir d'un code partiellement sécurisé, telle qu'une application Web ASP.NET moyennement sécurisée, vous devez mettre en sandbox les appels vers les fonctions DPAPI non gérées. Pour ce faire, apportez les modifications suivantes :

  • Affirmez l'autorisation de code non géré dans le code wrapper DPAPI. Cela signifie qu'un code appelant ne requiert pas d'autorisation de code non géré.

  • Autorisez le code appelant à l'intérieur du wrapper en demandant l'autorisation personnalisée EncryptionPermission. L'appel Demand se produit avant l'appel Assert, en accord avec le modèle d'utilisation Demand/Assert. Pour plus d'informations sur l'utilisation sécurisée de Assert, consultez la section « Assert et RevertAssert » du module 8 « La sécurité d'accès au code en pratique ».

  • Pour modifier le wrapper géré DPAPI

    1. Créez le wrapper géré DPAPI en suivant les instructions de l'article « Procédure : création d'une bibliothèque DPAPI ».

    2. Ajoutez une référence à l'assembly CustomPermission.

    3. Ouvrez dataprotection.cs à partir de la bibliothèque de wrappers gérés et ajoutez les instructions using suivantes sous les instructions using existantes en haut du fichier.

      using System.Security;
      using System.Security.Permissions;
      using CustomPermissions;
      
    4. Localisez la méthode Encrypt dans dataprotection.cs et ajoutez le code suivant en haut du bloc try extérieur de cette méthode.

      // Définir storeFlag suivant la manière dont l'appelant 
      // emploie le wrapper DPAPI géré. 
      StorePermissionFlag storeFlag;
      if(Store.USE_MACHINE_STORE == store)
      {
        storeFlag = StorePermissionFlag.Machine;
      }
      else
      {
        storeFlag = StorePermissionFlag.User;
      }
      // Demande d'autorisation de cryptage personnalisée.
      (new EncryptionPermission(EncryptionPermissionFlag.Encrypt, storeFlag)).
                                                                     Demand();
      
      // Assertion de l'autorisation de code non géré.
      (new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
      // Maintenant, appeler P/Invoke pour appeler les fonctions DPAPI non gérées.
      
    5. Ajoutez le bloc finally suivant au bloc try extérieur dans la méthode Encrypt.

      finally
      {
        CodeAccessPermission.RevertAssert();
      }
      
    6. Localisez la méthode Decrypt dans dataprotection.cs et ajoutez le code suivant en haut du bloc try extérieur.

      StorePermissionFlag storeFlag;
      if(Store.USE_MACHINE_STORE == store)
      {
        storeFlag = StorePermissionFlag.Machine;
      }
      else
      {
        storeFlag = StorePermissionFlag.User;
      }  
        // Demand custom EncryptionPermission.
        (new EncryptionPermission(EncryptionPermissionFlag.Decrypt, storeFlag)).
                                                                    Demand();
        // Assert the unmanaged code permission.
        (new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
      
    7. Ajoutez le bloc finally suivant au bloc try extérieur dans la méthode Decrypt.

      finally
      {
        CodeAccessPermission.RevertAssert();
      }

Appel de DPAPI à partir d'une application Web moyennement sécurisée

Pour utiliser le wrapper géré DPAPI à partir d'une application Web moyennement sécurisée ou d'un code partiellement sécurisé, vous devez configurer la stratégie d'accès au code pour accorder au code l'autorisation personnalisée EncryptionPermission.

Dans cette étape, vous créez une application Web test puis vous modifiez la stratégie d'accès au code ASP.NET d'une application Web moyennement sécurisée pour lui accorder l'autorisation EncryptionPermission.

  • Pour créer une application Web test

    1. Ajoutez un nouveau projet d'application Web C# ASP.NET à votre solution actuelle.

    2. Ajoutez une référence dans l'assembly Dataprotection.dll.

    3. Ajoutez les champs suivants dans Webform1.aspx.

      • Un champ d'entrée pour les données à crypter. Utilisez l'ID txtDataToEncrypt.

      • Un champ pour les données cryptées. Utilisez l'ID txtEncryptedData.

      • Un champ pour les données décryptées. Utilisez l'ID txtDecryptedData.

      • Un bouton Encrypt. Utilisez l'ID btnEncrypt.

      • Un bouton Decrypt. Utilisez l'ID btnDecrypt.

      • Une étiquette pour un message d'erreur. Utilisez l'ID lblError.

    4. Ajoutez l'instruction using suivante en haut du fichier WebForm1.aspx.cs sous les instructions using existantes.

      using DataProtection;
      
    5. Ajoutez le code suivant pour le gestionnaire d'événements par clic sur le bouton Encrypt.

      private void btnEncrypt_Click(object sender, System.EventArgs e)
      {
        DataProtector dp = new DataProtector(
                                    DataProtector.Store.USE_MACHINE_STORE );
        try
        {
          byte[] dataToEncrypt = Encoding.ASCII.GetBytes(txtDataToEncrypt.Text);
          // Aucun paramètre facultatif d'entropie de transfert dans cet exemple
          // Possibilité de transférer une valeur aléatoire (stockée par l'application) pour plus de sécurité
          // quand DPAPI est utilisé avec la base machine.
          txtEncryptedData.Text =
                   Convert.ToBase64String(dp.Encrypt(dataToEncrypt,null));
        }
        catch(Exception ex)
        {
          lblError.ForeColor = Color.Red;
          lblError.Text = "Exception.<br>" + ex.Message;
          return;
        }
        lblError.Text = "";
      }
      
    6. Ajoutez le code suivant pour le gestionnaire d'événements par clic sur le bouton Decrypt.

      private void btnDecrypt_Click(object sender, System.EventArgs e)
      {
        DataProtector dp = new DataProtector(DataProtector.Store.USE_MACHINE_STORE);
        try
        {
          byte[] dataToDecrypt = Convert.FromBase64String(txtEncryptedData.Text);
          // Le paramètre facultatif d'entropie est nul. 
          // Si l'entropie était utilisée dans la méthode Encrypt, le même paramètre d'entropie 
          // devrait être fourni ici.
          txtDecryptedData.Text = 
               Encoding.ASCII.GetString(dp.Decrypt(dataToDecrypt,null));
        }
        catch(Exception ex)
        {
          lblError.ForeColor = Color.Red;
          lblError.Text = "Exception.<br>" + ex.Message;
          return;
        }
        lblError.Text = "";
      }
      
    7. Configurez l'application Web pour une sécurisation moyenne en ajoutant l'élément suivant au fichier Web.config de l'application à l'intérieur de la section <system.web>.

      <trust level="Medium" />
      
    8. Générez la solution.

  • Pour modifier une stratégie moyennement sécurisée

    1. Ouvrez le fichier de la stratégie moyennement sécurisée à l'aide de Visual Studio® .NET ou du Bloc-notes. Le fichier de la stratégie se trouve à l'emplacement suivant.

      %windir%\Microsoft.NET\Framework\{version}\CONFIG\web_mediumtrust.config
      
    2. Déclarez l'autorisation EncryptionPermission en ajoutant l'élément <SecurityClass> suivant à l'élément <SecurityClasses>.

      <SecurityClass Name="EncryptionPermission" 
                     Description="CustomPermission.EncryptionPermission, 
                                  CustomPermission, Version=1.0.0.1, 
                                  Culture=neutral, 
                                  PublicKeyToken=951cd7d57a536a94"/>
      

      Configurez la valeur d'attribut PublicKeyToken sur le jeton de clé publique spécifique à votre assembly. Pour extraire le jeton de clé publique spécifique à votre assembly d'autorisation personnalisée, utilisez la commande suivante.

      sn -T custompermission.dll
      

      Remarque : utilisez un switch -T majuscule.

    3. Localisez le jeu d'autorisations nommé ASP.NET dans le fichier de stratégie moyennement sécurisée et ajoutez l'élément d'autorisation suivant.

      <IPermission class="EncryptionPermission" 
                   version="1" Flags="Encrypt,Decrypt" 
                   Stores="Machine,User">
      </IPermission>
      

      Cette autorisation accorde aux applications Web moyennement sécurisées l'autorisation EncryptionPermission non restreinte parce qu'elle permet de crypter et de décrypter des données et d'utiliser le magasin de l'ordinateur ou d'utilisateurs DPAPI. L'élément ci-dessus indique la syntaxe prise en charge. Il est équivalent à celui-ci :

      <IPermission class="EncryptionPermission" 
                   version="1" Unrestricted="true" >
      </IPermission>
      

      Vous pouvez accorder au code une autorisation restreinte en utilisant uniquement les attributs pertinents. Par exemple, pour contraindre le code à décrypter les données en utilisant uniquement la clé de l'ordinateur dans le magasin de l'ordinateur, utilisez l'élément suivant.

      <IPermission class="EncryptionPermission" 
                   version="1" Flags="Decrypt" 
                   Stores="Machine">
      </IPermission>
      
    4. Enregistrez le fichier de la stratégie.

      Vous pouvez maintenant exécuter l'application Web test et vérifier que vous pouvez crypter et décrypter des données en utilisant DPAPI à partir d'une application Web partiellement sécurisée.

Pour plus d'informations sur la mise en sandbox du code hautement privilégié et sur l'utilisation de la stratégie de sécurité d'accès au code ASP.NET, consultez le module 9 « Utilisation de la sécurité d'accès au code avec ASP.NET ».

Cela vous a-t-il été utile ?
(1500 caractères restants)
Microsoft réalise une enquête en ligne pour recueillir votre opinion sur le site Web de MSDN. Si vous choisissez d’y participer, cette enquête en ligne vous sera présentée lorsque vous quitterez le site Web de MSDN.

Si vous souhaitez y participer,
© 2013 Microsoft. Tous droits réservés.