Signer sa Bibliothèque

 ====== Signature des Assemblies ======


===== Obtenir la signature forte d'une assembly et son Token =====

  C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>sn.exe -Tp C:\DATA2\ETRESO-DEV\eTreso.Batch\Treso.Cost\lib\EntLib

\5.0\Microsoft.Practices.Unity.Interception.dll

===== Introduction =====

On parle de clé publique et de clé privée pour les algorithmes de chiffrement asymétrique. Ces clès permettent de crypter et de décrypter un message, elles seules permettent cette action. La clé publique ne doit pas être gardée secrète et peut être diffusée sans que la confidentialité du message ne soit affectée, par contre, la clé privée, comme son nom l'indique doit rester privée, sa divulgation rendrait ineficace le cryptage, car elle permet de décrypter le message. Pour résumer la clé publique sert à coder un message, alors que la clé privée sert à le décoder. Mais attention, le terme publique et privée sont subjectif, en effet, chacune des clés peu remplir ce rôle, c'est juste que l'on attribue un rôle à chacune, rôle qui bien évidemment n'est plus interchangeable par la suite. La longueur des clès est exprimée en bits, elle va généralement de 128 à 1024 bits suivant le type de clé et d'algorithme. Seuls les algorithmes asymétriques utilisent un jeu de deux clès, les algorithmes symétriques eux, n'utilisent qu'une seule clé.

Dans le contexte de la signature d'une assembly, on la signe au préalable avec la clé privée uniquement. La clé publique quant à elle nous servira à contrôler la validité de cette signature.


Qu'est-ce qu'une signature ?


Une signature électronique permet principalement de garantir que le contenu d'un document n'a pas été modifié aprés qu'il ait été signé. Appliqué aux assembly .Net elle garanti l'intégrité du contenu d'origine. Le procédé de signature d'assembly prend donc tout son sens en termes de sécurité et de garantie d'authenticité d'un programme.


===== Signature d'Assembly =====



La signature d'une assembly .Net comporte deux composantes fondamentales : hashage de son contenu et un nom fort.


==== Nom Fort ====



Un nom fort, ou "Strong Names" en anglais (d'ailleurs au cours de cet article nous utiliserons la version française et anglaise sans distinction) correspond à un ensemble d'éléments qui permettent d'identifier avec certitude une assembly donnée. Un nom fort est donc composé des éléments suivants :


    Une version

    Un nom simple

    Une clé publique

    Une clé privée

    Ainsi qu'une culture et une architecture CPU (x86 / x64) optionnelles


Une version est simplement une séquence de quatre chiffres agencés de la sorte :

Numéro majeur de version - Numéro mineur de version - Numéro de "build" - Numéro de révision, cela peut être par exemple "2.7.3.6".


Un nom simple, il s'agît du nom que le développeur à donné à l'assembly, généralement c'est le nom du fichier sans son extension (.dll, .exe,...), il faut donc bien faire attention à ne pas mélanger cela avec un Namespace ou à un nom de classe.


Une clé publique, qui va permettre à l'environnement .Net de vérifier la signature de l'assembly signée avec une clé privée. En effet, une et une seule clé publique correspond à une clé privée. La clé publique sert donc de référent. La clé publique peut être communiquer sans risque. Cette clé publique est toujours intégrée à une assembly signée, et est assez facile à récupérer au sein d'une assembly pour tout développeur .Net aguerri.


Une clé privée, cette clé est celle qui a servie à signer l'assembly, sa valeur doit rester secrète, en effet elle seule garantie l'authenticité et la non corruption du contenu d'une assembly. Sa gestion est donc sensible, mais nous y reviendrons plus tard.

.Net




Une culture, pour simplifier il s'agît de la langue et des réglages régionaux, cela peut être US, FR ou autre...


Une architecture de processeur, information en relation avec la machine de destination prévue pour l'assembly, à ce jour Intel (par exemple x86, x64 ou même Itanium)."


Un nom fort est donc un ensemble de procédés et de valeurs qui garantissent l'authenticité et la non corruption d'une assembly. Un nom fort est donc un composant de la technologie .Net qui peut s'avérer extrêmement intéressant dans la gestion de la sécurité. De plus, la signature d'assembly est indispensable pour la gestion du versionning d'assembly ou encore pour placer une assembly dans le GAC (Global Assembly Cache).


==== Hashage de l'assembly ====

En l'état, ce que nous savons de la signature d'une assembly est le fait que l'on utilise un certains nombres de paramètres pour identifier de manière unique une assembly, notamment par le biais d'une clé publique, ou plutôt d'un jeton correspondant à cette clé publique qui est intégré directement dans l'assembly. Cependant, il manque un élément important de la signature, en effet jusqu'ici rien ne prouve qu'une assembly signée n'ait pas été modifiée depuis qu'elle a été compilée par le développeur. Pour ce faire, un autre procédé va entrer en jeu, il s'agit du hashage. Voyons cela plus en détails.


Tout d'abord le hashage est un procédé mathématique reposant sur des algorithmes permettant de créer une sorte de condensé unique d'un texte ou du moins d'en ensemble de caractères, condensé à partir duquel, il sera absolument impossible de retrouver le texte original, c'est le propre du hashage d'être unidirectionnel et définitif. Pour résumer, après hachage d'une chaîne de caractères on obtient un condensé unique et définitif appelé hash, permettant d'identifier de manière unique et certaine un texte, qui dans notre cas sera le code IL (Intermediate Language) d'une assembly ainsi que certains paramètres de son manifest.


Ce hash est calculé lors de la compilation de notre code (VB.Net, C# ou autre…) en IL, bien évidemment ce hash n'est calculé que si l'on à indiqué au compilateur que l'on souhaitait signer notre assembly. Après calcul de ce hash, celui-ci est encrypté à l'aide de la clé privée, et inscrit dans notre assembly. Dès lors je pense que vous pouvez dors et déjà entrevoir la suite... La clé publique qui à été inscrite dans le manifeste de notre assembly, c'est-à-dire dans les métadonnées, va servir à décoder le hash qui y est stocké, et sera comparé avec le résultat du hachage obtenu par l'environnement d'exécution de .Net lors du chargement de l'assembly. Si le hash décrypté par la clé publique contenu dans l'assembly est semblable au hash calculé par l'environnement d'exécution alors l'assembly peut être chargée, dans le cas contraire une exception est levée, et le chargement annulé.


Ainsi grâce à ce procédé de hashage l'on peut déterminer avec certitude si l'assembly à été modifiée ou non depuis qu'elle à été signée par le développeur. Cette certitude repose bien entendu sur la non divulgation de la clé privée qui a servie au cryptage du hash obtenu au moment de la signature.


Au cours de cette partie nous avons pu voir que la signature d'une assembly repose sur un Strong Name qui est un ensemble d'éléments, ainsi que sur le calcul d'un hash de son contenu. La conjugaison des deux va permettre d'identifier avec certitude et de manière unique une assembly, et de garantir que celle-ci n'a pas été modifiée depuis qu'elle a été signée par le développeur à l'aide d'un couple clé publique/clé privée. Même si ce procédé semble est très utile et performant il possède, comme nous le verrons un peu plus tard, certaines limites et contraintes, il participera sans aucun doute au processus de sécurisation du code d'une application, mais il ne peut pas prétendre à incarner la sécurité à lui tout seul. 


===== Signature d'assembly dans un processus de développement =====


Jusqu'ici nous avons abordé la signature d'assembly avec des noms forts d'un point de vue relativement théorique. Ici nous allons nous placer dans une optique plus concrète, en voyant comment il est possible d'intégrer cette sécurité au sein d'un processus de développment. Cela va consister principalement à voir quels sont les inconvénients de la signature, ainsi de quelle manière il est possible de gérer au mieux la sécurité de la clé privée, qui est la clé de voute de la signature. 


==== Inconvénients et Avantages ====

Tout procédé qui présente des avantages, présente également des inconvéniants, la signature d'assembly n'échappe pas à la règle. D'ailleurs dans notre cas précis il est plus judicieux de parler de contrainte que d'inconvéniants. En effet, vous allez voir que signer ses assemblies peut se révéler assez lourd si l'on ne s'y prends pas correctement, surtout en cas de gros dévloppement.


La contrainte majeur de la signature d'assembly est paradoxalement la sécurité. Cela s'explique très facilement lorsque l'on comprends que la fiabilité de cette signature repose sur le secret de la clé privée, tout repose sur cette clé. Si la clé privée est dévoilée, alors le secret, est donc la signature tombe, ce n'est ni plus ni moins qu'un éléments relatif à la cryptographie employants de algorithmes assymétriques. Nous voyons donc que la contrainte majeur est le fait que la sécurité de génération et de stockage de la clé provée doit être total.


Une autre contrainte découlant de la première est qu'il va falloir utiliser en cas de gros développement notamment des astuces quand à la signature d'assembly en cours de développement, nous le verrons en particulier avec le "Delay Signing" et le "Test Key Signing" qui sont deux procédés permettant de n'avoir à signer définitivement nos assemblies qu'une fois le développement terminé, sans pour autant devoir être privé des avantages et des impératifs procurés par la signature au cours du processus de développement (notamment en cas d'utilisation du versionning dans le GAC et du besoin d'avoir des noms forts pour les assemblies).


Et enfin, un réel incovéniant, lui lié au "Delay Signing" que nous allons voir juste aprés est le fait de devoir désactivé la vérification réalisée par le CLR lors du chargement de l'assembly, en effet cela peut être une brèche relativement importante dans la sécurité du poste de développement, partant bien évidemment du principe qu'une telle opération ne devra jamais être réalisée en environnement de production. Heureusement, nous allons voir que .Net 2.0 nous apporte quelques évolutions bien précieuses dans ce domaine. 


5.2. Le delay signing▲


Une solution permettant de protéger beaucoup plus efficacement la clé privée, est le "Delay Signing", ou la signature différée, voyons la plus en détails sans plus tarder.

5.2.1. Présentation▲


Comme nous l'avons vu précédemment, l'utilisation de la clé privée par un grand nombre de personnes sur de multiples machines est un risque au plan de la sécurité. Pour palier à ce problème, il existe une solution pour contourner cela et ne pas être obligé de faire circuler la clé privé : c'est le "delay signing", on pourrait traduire cela par "signature différée". Cela consiste à utiliser uniquement le jeton de la clé publique pour l'intégrer dans l'assembly, ainsi elle possède un nom fort (ce qui est nécessaire dans nombre de situations de développement), mais par contre elle ne peut pas passer la validation de l'environnement d'exécution, il faut donc désactiver cette vérification jusqu'à ce que la signature avec la clé privée soit effectivement réalisée, signature qui interviendra généralement juste avant la livraison du produit, et sera effectuée par un nombre restreint de personnes pour des raisons évidentes de sécurité.


Voici la démarche à suivre pour utiliser le "delay signing"


Commentaires

Posts les plus consultés de ce blog

Sécurité des Applications

Principes de la Programmation Orientée Objet

Principe de Responsabilité Unique