3ae834d48dde3423583c5ef798f463c0786dc134
[crypto_lab2.git] / rapport / main.tex
1 \documentclass[a4paper,10pt]{article}
2
3 \usepackage[francais]{babel}
4 \usepackage[utf8]{inputenc}
5 \usepackage[T1]{fontenc}
6 \usepackage{lmodern}
7
8 \usepackage{graphicx}
9 \usepackage{listings}
10 \usepackage{url}
11 \usepackage{upquote}
12 \usepackage{color}
13 \usepackage[usenames,dvipsnames]{xcolor}
14
15 %%% URLs %%%
16 \urldef{\dotnetcrypto}\url{http://msdn.microsoft.com/en-us/library/System.Security.Cryptography%28v=vs.110%29.aspx}
17 \urldef{\monodevelop}\url{http://www.monodevelop.com/}
18 \urldef{\rsacryptoserviceprovider}\url{http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider%28v=vs.110%29.aspx}
19 \urldef{\rngcryptoserviceprovider}\url{http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider%28v=vs.110%29.aspx}
20 \urldef{\rsasecurity}\url{http://en.wikipedia.org/wiki/RSA_Security}
21 \urldef{\wikiml}\url{http://en.wikipedia.org/wiki/ML_%28programming_language%29}
22 \urldef{\rsaxmlformat}\url{http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa.toxmlstring%28v=vs.110%29.aspx}
23
24 \title{ICR - Labo \#2 : \textit{Conception et implémentation d'un container sécurisé pour des données médicales}}
25 \author{G.Burri}
26
27 \lstdefinelanguage{FSharp}%
28 {morekeywords={let, new, match, with, rec, open, module, namespace, type, of, member, %
29 and, for, while, true, false, in, do, begin, end, fun, function, return, yield, try, %
30 mutable, if, then, else, cloud, async, static, use, abstract, interface, inherit, finally },
31 otherkeywords={ let!, return!, do!, yield!, use!, var, from, select, where, order, by },
32 keywordstyle=\color{blue}\bfseries,
33 sensitive=true,
34 basicstyle=\ttfamily,
35 breaklines=true,
36 xleftmargin=\parindent,
37 aboveskip=\bigskipamount,
38 tabsize=4,
39 morecomment=[l][\color{OliveGreen}]{///},
40 morecomment=[l][\color{OliveGreen}]{//},
41 morecomment=[s][\color{OliveGreen}]{{(*}{*)}},
42 morestring=[b]",
43 showstringspaces=false,
44 literate={`}{\`}1,
45 stringstyle=\color{red},
46 }
47
48 \begin{document}
49
50 \nocite{*}
51
52 \maketitle
53
54
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 \section{Introduction}
57
58 Le but de ce laboratoire est de définir les algorithmes cryptographiques et leurs paramètres afin de sécuriser des données médicales. Une donnée médicale est représentée par un fichier qui devra être sécurisé au sein d'un container dont le format sera défini par nos soins. Une implémentation sera ensuite proposée.
59
60
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 \section{Niveaux de sécurité}
63
64 \subsection{Quel est le niveau de sécurité que l'on souhaite atteindre ?}
65
66 Le niveau souhaité est de 128 bits. Cela implique l'utilisation d'une clef \emph{AES} de 128 bits et de clefs \emph{RSA} de 3072 bits d'après~\cite{wiki-key-size}.
67
68 Les éléments de sécurité suivants sont requis :
69
70 \begin{itemize}
71 \item Confidentialité : les données chiffrées ne doivent pas pouvoir être décryptées par un attaquant.
72 \item Authenticité : un attaquant ne doit pas pouvoir forger un container. Une signature est réalisée à l'aide d'une paire de clefs \emph{RSA} publique-privée.
73 \item Intégrité : il ne faut pas que les données chiffrées aient pu être altérées par un attaquant.
74 \end{itemize}
75
76
77 \subsection{Comment s'assure-t-on que les données sont stockées de manière confidentielle ? En particulier en ce qui concerne les méta-données ?}
78
79 Les méta-données ainsi que les données sont chiffrées ensemble. Voir le format du container décrit à la section~\ref{sec:format_container}.
80
81
82 \subsection{Comment s'assure-t-on que les données stockées sont authentiques ? Quels sont les risques à prendre en compte ?}
83
84 L'empreinte des données chiffrées est signée à l'aide d'une clef privée donnée en paramètre de l'\emph{API} : ceci représente la signature qui est placée dans le container. Lors du déchiffrement, la clef publique correspondante est fournie puis utilisée pour vérifier la signature avec l'empreinte des données chiffrées.
85
86
87 \subsection{Comment s'assure-t-on que les données stockées sont intègres ?}
88
89 Cela est réalisé avec un \emph{MAC}, dans notre cas nous utilisons \emph{HMAC-SHA256} sur l'ensemble des données chiffrées (\emph{Encrypt-then-MAC}).
90
91
92 \subsection{Quels sont les clefs cryptographiques requises qu'il est nécessaire de gérer ?}
93
94 \subsubsection{Clefs externes}
95
96 Concerne les clefs externes à l'\emph{API}.
97
98 \begin{itemize}
99 \item Une paire de clefs \emph{RSA-3072} pour la signature.
100 \item Une paire de clefs \emph{RSA-3072} pour le chiffrement des clefs \emph{AES}.
101 \end{itemize}
102
103
104 \subsubsection{Clefs internes}
105
106 Concerne les clefs gérées à l'intérieur du container.
107
108 \begin{itemize}
109 \item Une clef de 128 bits pour \emph{AES}.
110 \item Une clef de 256 bits pour \emph{HMAC}.
111 \end{itemize}
112
113 Ces clefs sont générées aléatoirement à chaque création d'un container.
114
115
116 \section{Choix des algorithmes et des paramètres}
117
118 \begin{itemize}
119 \item \emph{RSA-3072} pour la signature ainsi que pour le chiffrage des clefs \emph{AES} et \emph{HMAC}. Le bourrage \emph{OAEP} (\emph{PKCS\#1 v2}) est utilisé ;
120 \item \emph{HMAC-SHA256} pour la vérification de l'intégrité ;
121 \item \emph{AES-CBC128} pour le chiffrement symétrique du contenu du fichier et des méta-données associées. Le bourrage \emph{PKCS7} est utilisé.
122 \end{itemize}
123
124 D'après~\cite{wiki-key-size}, la société \emph{RSA Security}\footnote{\rsasecurity} annonce qu'une taille de clefs \emph{RSA} de 3072 bits est suffisante pour une utilisation au delà de 2030. Cela dépend également du niveau d'importance des documents que l'on souhaite chiffrer dans la mesure ou une attaque demande énormément de moyens.
125
126 Toujours d'après~\cite{wiki-key-size}, une taille de clef \emph{AES} de 128 bits reste, actuellement, hors de portée de toutes attaques.
127
128
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 \section{Format du container}
131 \label{sec:format_container}
132
133 Le format est défini comme suit en \emph{EBNF}. Les valeurs entre crochets correspondent soit à une taille en bits soit à un type.
134
135 \begin{lstlisting}[frame=single, breaklines, basicstyle=\ttfamily\footnotesize]
136 container = header, ciphertext ;
137 header = mac[256], signature[3072], keys[3072] ;
138 ciphertext = AES(plaintext) ;
139 plaintext = meta-data, file-content ;
140 meta-data = nb-meta-data[byte], { key-value-pair } ;
141 key-value-pair = key[string], value[string] ;
142 string = size[vint], content-utf8 ;
143 \end{lstlisting}
144
145 \texttt{nb-meta-data} est le nombre de paires clef-valeur des méta-données.
146
147 \texttt{keys} correspond aux clefs $k_c$ et $k_a$ ainsi qu'à l'\emph{IV}, le tout chiffré avec \emph{RSA-3072}. La taille des données à chiffrer est égale à $k_c + k_a + iv = 128 + 256 + 128 = 512\,bits$.
148
149 Les méta-données (\texttt{meta-data}) peuvent contenir, par exemple, le nom du fichier, sa date de création, ses droits, ou toutes autres données associées.
150
151 Le type \texttt{vint} correspond à un entier de taille variable, initialement occupant un octet.
152
153 Comme les clefs (\emph{AES} et \emph{HMAC-SHA256}) sont différentes à chaque chiffrement, que le \emph{MAC} dépend de sa clef et des données chiffrées et que la signature dépend du \emph{MAC} alors l'ensemble des octets des différentes parties du fichier résultat va être fortement différent d'un chiffrement à l'autre pour le même fichier en entrée.
154
155
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 \section{Processus}
158
159 \subsection{Chiffrement}
160
161 Entrées :
162
163 \begin{itemize}
164 \item $f$ : fichier
165 \item $k_{pub}$ : clef publique RSA
166 \item $k_{signpriv}$ : clef privée de signature RSA
167 \end{itemize}
168
169
170 Sortie :
171
172 \begin{itemize}
173 \item $c$ : container chiffré.
174 \end{itemize}
175
176
177 Processus :
178
179 \begin{enumerate}
180 \item Génération d'une clef 128 bits pour \emph{AES} $\rightarrow k_c$.
181 \item Génération d'une clef 256 bits pour \emph{MAC} $\rightarrow k_a$.
182 \item Génération d'un \emph{IV} 128 bits pour le mode \emph{CBC} $\rightarrow iv$.
183 \item Construction du $plaintext$ à partir de $f$, voir format décrit à la section~\ref{sec:format_container}.
184 \item Chiffrement du $plaintext$ avec \emph{AES-CBC128}, $k_c$ et $iv \rightarrow ciphertext$.
185 \item Calcul du \emph{HMAC-SHA256} de $ciphertext$ $\rightarrow mac$.
186 \item Signature de $mac$ avec $k_{signpriv}$ $\rightarrow sig$.
187 \item Chiffrement de $k_c + k_a + iv$ avec $k_{pub} \rightarrow keys$.
188 \item $mac + sig + keys + ciphertext \rightarrow c$.
189 \end{enumerate}
190
191 Où $+$ dénote la concaténation.
192
193
194 \subsection{Déchiffrement}
195
196 Entrée :
197
198 \begin{itemize}
199 \item $c$ : container chiffrés
200 \item $k_{priv}$ : clef privée RSA
201 \item $k_{signpub}$ : la clef publique de signature RSA
202 \end{itemize}
203
204 Sortie :
205
206 \begin{itemize}
207 \item $f$ : fichier original
208 \end{itemize}
209
210
211 Processus :
212
213 \begin{enumerate}
214 \item Lecture de $mac$, calcul de $mac'$ sur $c$, comparaison des deux valeurs afin de vérifier l'intégrité.
215 \item Vérification de la signature avec $k_{signpub}$.
216 \item Déchiffrement de $k_c + k_a + iv$ avec $k_{priv}$.
217 \item Déchiffrement du reste des données ($ciphertext$) $\rightarrow f$.
218 \end{enumerate}
219
220 Ce processus nécessite deux cycles de lecture des données, le premier pour le calcul de $mac'$ et le deuxième pour le déchiffrement. Le deuxième cycle n'est effectué que si l'intégrité et l'authenticité ont été validées.
221
222
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 \section{Implémentation}
225
226 Nous utilisons ici la plate-forme \emph{.NET} ainsi que le langage \emph{F\#}, un dialecte de \emph{ML}\footnote{\wikiml}. L'ensemble des éléments cryptographiques requis sont fournis par \emph{.NET} \footnote{\dotnetcrypto}.
227
228 Deux \emph{assemblies} sont créées :
229
230 \begin{itemize}
231 \item \emph{CryptoFile} : \emph{Library} mettant à disposition l'\emph{API} de chiffrement de fichier et de déchiffrement de container.
232 \item \emph{CryptoFileTests} : Exécutable utilisant la \emph{library} \emph{CryptoFile} et permettant d'utiliser l'\emph{API} à l'aide d'arguments fournis par la ligne de commande.
233 \end{itemize}
234
235 \subsection{Utilisation}
236
237 Il est possible de compiler la solution à l'aide de \emph{MonoDevelop}\footnote{\monodevelop} ou de \emph{Visual Studio 2012}. Le script \emph{Bash} \texttt{labo2-fsharp/run\_tests.sh} permet de compiler la solution puis d'exécuter un certain nombre de tests.
238
239 À partir du dossier \texttt{labo2-fsharp} et après avoir compiler en \emph{release} la solution, voici ce qu'il est possible d'effectuer :
240
241 \begin{itemize}
242 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe tests} : Réalise une série de tests.
243 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe encrypt <file> <container>} : Chiffre le fichier \texttt{<file>} vers le container \texttt{<container>}.
244 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe decrypt <container> <output directory>} : Déchiffre le container \texttt{<container>} dans le dossier \texttt{<output directory>}.
245 \end{itemize}
246
247 Les clefs publiques et privées pour le chiffrement ainsi que pour la réalisation de la signature se trouvent dans les fichiers \texttt{keys-crypt.priv}, \texttt{keys-crypt.pub}, \texttt{keys-sign.priv} et \texttt{keys-sign.pub}. Ceux-ci sont automatiquement générés dans le cas où ils sont introuvables.
248
249
250 \subsection{Organisation du code}
251
252 La \emph{ĺibrary} \emph{CryptoFile} est composée de trois fichiers :
253
254 \begin{itemize}
255 \item \emph{Types.fs} : Quelques types publics.
256 \item \emph{Crypto.fs} : Toutes les primitives cryptographiques nécessaires.
257 \item \emph{UnitTests.fs} : Quelques tests unitaires du module \emph{Crypto}.
258 \item \emph{API.fs} : L'interface publique de la \emph{library}. Elle est détaillée à la section~\ref{sec:api}.
259 \end{itemize}
260
261 \subsubsection{API}
262 \label{sec:api}
263
264 Voici la partie publique de la \emph{library} \emph{CryptoFile}.
265
266 \begin{minipage}{\linewidth} % Pour éviter que le listing soit séparé sur deux pages.
267 \begin{lstlisting}[language=FSharp, frame=single, basicstyle=\ttfamily\footnotesize]
268 module API =
269 (* Generates a pair of keys (public * private)
270 to be used in the following two functions.
271 You have the reponsability of keeping
272 the private part secret. *)
273 let generatKeysPair : Key * Key
274
275 let encryptFile (inputFilePath : string)
276 (outputFilePath : string)
277 (signaturePrivKey: Key)
278 (cryptPubKey : Key)
279
280 let decryptFile (sourceFilePath : string)
281 (targetDirPath : string)
282 (signaturePubKey: Key)
283 (decryptPrivKey : Key)
284 \end{lstlisting}
285 \end{minipage}
286
287 Les formats des clefs, publique et privée, sont décrits sur cette page~\footnote{\rsaxmlformat}.
288
289
290 \subsection{Mesures de performance}
291
292 Quelques mesures sur un fichier de 871 MiB ont été effectuées sous \emph{Linux} avec \emph{Mono} 3.10.0 ainsi que sous \emph{Windows 8.1} avec \emph{Visual Studio 2012}. Il est a noter que l'implémentation \emph{AES} de \emph{Mono} est en \emph{C\#} et n'utilise évidemment pas l’accélération matérielle d'\emph{Intel} présente sur la machine : \emph{AES-NI}.
293
294 Les tests sous \emph{Windows 8} ont été fait sur une machine ne possédant pas \emph{AES-NI}. Cet ensemble d'instructions est normalement supporté par l’implémentation du \emph{runtime} \emph{.NET} de \emph{Microsoft}.
295
296 \begin{tabular}{ l | r | r | r | r }
297 & \multicolumn{2}{c|}{Chiffrement} & \multicolumn{2}{|c}{Déchiffrement} \\
298 \cline{2-5}
299 & \multicolumn{1}{c}{\emph{Mono}} & \multicolumn{1}{|c|}{\emph{MS .NET}} & \multicolumn{1}{|c|}{\emph{Mono}} & \multicolumn{1}{c}{\emph{MS .NET}} \\
300 \cline{2-5}
301 Temps & 39 s & 20 s & 48 s & 20 s \\
302 Mémoire utilisée & 7.0 MiB & 14 MiB & 15.2 MiB & 13.9 MiB \\
303 Taux \emph{CPU} & 1 x 100 \% & 1 x 100 \% & 1 x 100 \% & 1 x 100 \% \\
304 \end{tabular}
305
306 \subsubsection{Génération de paire de clefs \emph{RSA}}
307
308 La génération de clefs \emph{RSA} est très lente sous \emph{Mono}. Pour une taille de 2048 bits cela prend environ une seconde, pour une taille de 3072 bits cela prend environ dix secondes.
309
310
311 \section{Analyse de la sécurité de l'implémentation}
312
313 \subsection{Quelles sont les parties critiques du code et comment s'assure-t-on que ces parties soient correctement implémentées ?}
314
315 Le choix des algorithmes, de leurs paramètres et de leur implémentation est une partie critique. Il est possible de se référer aux recommandations de certains organismes comme par exemple le \emph{NIST}\footnote{\emph{National Institute of Standards and Technology}}.
316
317 La génération des clefs \emph{AES} doit être faite avec un générateur cryptographique. Dans notre cas nous utilisons \emph{RNGCryptoServiceProvider}\footnote{\rngcryptoserviceprovider}.
318
319
320 \subsection{Quels sont les points faibles restants et quelles sont les possibilités de les corriger ?}
321
322 Les deux clefs privées \emph{RSA} doivent absolument rester secrètes. Pour ce faire, il faudrait chiffrer les fichiers contenant ces clefs à l'aide d'une \emph{passphrase} robuste et garder celle-ci en sécurité.
323
324
325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 \section{Conclusion}
327
328 Ce laboratoire a permis de mettre en évidence la problématique de la sécurisation de fichiers ainsi que de leurs méta-données associées. Le choix de bons algorithmes et des bons paramètres associés est capital pour garantir la sécurité des fichiers.
329
330
331 \bibliographystyle{plain}
332 \bibliography{main}
333
334 \end{document}