Clean up.
[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{\rsasecurity}\url{http://en.wikipedia.org/wiki/RSA_Security}
20
21 \title{ICR - Labo \#2 : \textit{Conception et implémentation d'un container sécurisé pour des données médicales}}
22 \author{G.Burri}
23
24 \lstdefinelanguage{FSharp}%
25 {morekeywords={let, new, match, with, rec, open, module, namespace, type, of, member, %
26 and, for, while, true, false, in, do, begin, end, fun, function, return, yield, try, %
27 mutable, if, then, else, cloud, async, static, use, abstract, interface, inherit, finally },
28 otherkeywords={ let!, return!, do!, yield!, use!, var, from, select, where, order, by },
29 keywordstyle=\color{blue}\bfseries,
30 sensitive=true,
31 basicstyle=\ttfamily,
32 breaklines=true,
33 xleftmargin=\parindent,
34 aboveskip=\bigskipamount,
35 tabsize=4,
36 morecomment=[l][\color{OliveGreen}]{///},
37 morecomment=[l][\color{OliveGreen}]{//},
38 morecomment=[s][\color{OliveGreen}]{{(*}{*)}},
39 morestring=[b]",
40 showstringspaces=false,
41 literate={`}{\`}1,
42 stringstyle=\color{red},
43 }
44
45 \begin{document}
46
47 \nocite{*}
48
49 \maketitle
50
51
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 \section{Introduction}
54
55 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.
56
57
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 \section{Niveaux de sécurité}
60
61 \subsection{Quel est le niveau de sécurité que l'on souhaite atteindre ?}
62
63 \begin{itemize}
64 \item Confidentialité : les données chiffrées ne doivent pas pouvoir être décryptées par un attaquant.
65 \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.
66 \item Intégrité : il ne faut pas que les données chiffrées aient pu être altérées par un attaquant.
67 \end{itemize}
68
69
70 \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 ?}
71
72 Les méta-données ainsi que les données sont chiffrées ensemble. Voir le format du container décrit ci-après.
73
74
75 \subsection{Comment s'assure-t-on que les données stockées sont authentiques ? Quels sont les risques à prendre en compte ?}
76
77 L'empreinte des donné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 déchiffrer l'empreinte qui est comparée à l'empreinte des données.
78
79
80 \subsection{Comment s'assure-t-on que les données stockées sont intègres ?}
81
82 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}).
83
84
85 \subsection{Quels sont les clefs cryptographiques requises qu'il est nécessaire de gérer ?}
86
87 \subsubsection{Clefs externes}
88
89 Concerne les clefs externes à l'\emph{API}.
90
91 \begin{itemize}
92 \item Une paire de clefs \emph{RSA-2048} pour la signature.
93 \item Une paire de clefs \emph{RSA-2048} pour le chiffrement des clefs \emph{AES}.
94 \end{itemize}
95
96
97 \subsubsection{Clefs internes}
98
99 Concerne les clefs gérées à l'intérieur du container.
100
101 \begin{itemize}
102 \item Une clef de 128 bits pour \emph{AES}.
103 \item Une clef de 256 bits pour \emph{HMAC}.
104 \end{itemize}
105
106 Ces clefs sont générées aléatoirement à chaque création d'un container.
107
108
109 \section{Choix des algorithmes et des paramètres}
110
111 \begin{itemize}
112 \item \emph{RSA-2048} pour la signature ainsi que pour le chiffrage des clefs \emph{AES} et \emph{HMAC}. Le bourrage \emph{PKCS\#1 v1.5} est utilisé ;
113 \item \emph{HMAC-SHA256} pour la vérification de l'intégrité ;
114 \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é.
115 \end{itemize}
116
117 D'après \cite{wiki-key-size}, la société \emph{RSA Security}\footnote{\rsasecurity} annonce qu'une taille de clefs \emph{RSA} de 2048 bits est suffisante jusqu'en 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.
118
119 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.
120
121
122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123 \section{Format du container}
124
125 Le format est défini comme suit en \emph{EBNF}. Les valeurs entre crochets correspondent soit à une taille en bits soit à un type.
126
127 \begin{lstlisting}[frame=single, breaklines, basicstyle=\ttfamily\footnotesize]
128 container = header, ciphertext ;
129 header = mac[256], signature[2048], keys[2048] ;
130 ciphertext = AES(plaintext) ;
131 plaintext = meta-data, file-content ;
132 meta-data = nb-meta-data[byte], { key-value-pair } ;
133 key-value-pair = key[string], value[string] ;
134 string = size[vint], content-utf8 ;
135 \end{lstlisting}
136
137 \texttt{nb-meta-data} est le nombre de paires clef-valeur des méta-données.
138
139 \texttt{keys} correspond aux clefs $k_c$ et $k_a$ ainsi qu'à l'\emph{IV}, le tout chiffré avec \emph{RSA-2048}. La taille des données chiffrées est égale à $k_c + k_a + iv = 128 + 256 + 128 = 512\,bits$.
140
141 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.
142
143 Le type \texttt{vint} correspond à un entier de taille variable, initialement occupant un octet.
144
145 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.
146
147
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 \section{Processus}
150
151 \subsection{Chiffrement}
152
153 Entrées :
154
155 \begin{itemize}
156 \item $f$ : fichier
157 \item $k_{pub}$ : clef publique RSA
158 \item $k_{signpriv}$ : clef privée de signature RSA
159 \end{itemize}
160
161
162 Processus :
163
164 \begin{enumerate}
165 \item Génération d'une clef 128 bits pour \emph{AES} $\rightarrow k_c$.
166 \item Génération d'une clef 256 bits pour \emph{MAC} $\rightarrow k_a$.
167 \item Génération d'un \emph{IV} 128 bits pour le mode \emph{CBC} $\rightarrow iv$.
168 \item Construction du $plaintext$, voir format ci dessus.
169 \item Chiffrement du $plaintext$ avec \emph{AES-CBC128}, $k_c$ et $iv \rightarrow ciphertext$.
170 \item Calcul de MAC de $ciphertext$ $\rightarrow mac$.
171 \item Signature de $mac$ avec $k_{signpriv}$ $\rightarrow sig$.
172 \item Chiffrement de $k_c + k_a + iv$ avec $k_pub \rightarrow keys$.
173 \item Renvoie $mac + sig + keys + ciphertext$.
174 \end{enumerate}
175
176 Où $+$ dénote la concaténation.
177
178
179 \subsection{Déchiffrement}
180
181 Entrée :
182
183 \begin{itemize}
184 \item $c$ : container chiffrés
185 \item $k_{priv}$ : clef privée RSA
186 \item $k_{signpub}$ : la clef publique de signature RSA
187 \end{itemize}
188
189 Processus :
190
191 \begin{enumerate}
192 \item Lecture de $mac$, calcul de $mac'$ sur $c$ comparaison des deux afin de vérifier l'intégrité.
193 \item Vérification de la signature avec $k_{signpub}$.
194 \item Déchiffrement de $k_c + k_a + iv$ avec $k_{priv}$.
195 \item Déchiffrement du reste des données ($ciphertext$).
196 \end{enumerate}
197
198 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.
199
200
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 \section{Implémentation}
203
204 Nous utilisons ici la plate-forme \emph{.NET} ainsi que le langage \emph{F\#}. L'ensemble des éléments cryptographiques requis sont fournis par \emph{.NET} \footnote{\dotnetcrypto}.
205
206 Deux \emph{assemblies} sont créées :
207
208 \begin{itemize}
209 \item \emph{CryptoFile} : \emph{Library} mettant à disposition l'\emph{API} de chiffrement de fichier et de déchiffrement de container.
210 \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.
211 \end{itemize}
212
213 \subsection{Utilisation}
214
215 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.
216
217 À partir du dossier \texttt{labo2-fsharp} et après avoir compiler en \emph{release} la solution, voici ce qu'il est possible d'effectuer :
218
219 \begin{itemize}
220 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe tests} : Réalise une série de tests.
221 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe encrypt <file> <container>} : Chiffre le fichier \texttt{<file>} vers le container \texttt{<container>}.
222 \item \texttt{CryptoFileTests/bin/Release/CryptoFileTests.exe decrypt <container> <output directory>} : Déchiffre le container \texttt{<container>} dans le dossier \texttt{<output directory>}.
223 \end{itemize}
224
225 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.
226
227
228 \subsection{Organisation du code}
229
230 La \emph{ĺibrary} \emph{CryptoFile} est composée de trois fichiers :
231
232 \begin{itemize}
233 \item \emph{Types.fs} : Quelques types publics.
234 \item \emph{Crypto.fs} : Toutes les primitives cryptographiques nécessaires.
235 \item \emph{UnitTests.fs} : Quelques tests unitaires du module \emph{Crypto}.
236 \item \emph{API.fs} : L'interface publique de la \emph{library}. Elle est détaillée ci-après.
237 \end{itemize}
238
239 \subsubsection{API}
240
241 Voici la partie publique de la \emph{library} \emph{CryptoFile}.
242
243 \begin{minipage}{\linewidth} % Pour éviter que le listing soit séparé sur deux pages.
244 \begin{lstlisting}[language=FSharp, frame=single, basicstyle=\ttfamily\footnotesize]
245 module API =
246 (* Generates a pair of keys (public * private)
247 to be used in the following two functions.
248 You have the reponsability of keeping
249 the private part secret. *)
250 let generatKeysPair : Key * Key
251
252 let encryptFile (inputFilePath : string)
253 (outputFilePath : string)
254 (signaturePrivKey: Key)
255 (cryptPubKey : Key)
256
257 let decryptFile (sourceFilePath : string)
258 (targetDirPath : string)
259 (signaturePubKey: Key)
260 (decryptPrivKey : Key)
261 \end{lstlisting}
262 \end{minipage}
263
264
265 \subsection{Mesures de performance}
266
267 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} 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}.
268
269 Les tests sous \emph{Windows 8} ont été fait sur une machine ne possédant pas \emph{AES-NI}. Cette fonctionnalité est normalement utilisée par l’implémentation du \emph{runtime} \emph{.NET} de \emph{Microsoft} .
270
271 \begin{tabular}{ l | r | r | r | r }
272 & \multicolumn{2}{c|}{Chiffrement} & \multicolumn{2}{|c}{Déchiffrement} \\
273 \cline{2-5}
274 & \multicolumn{1}{c}{\emph{Mono}} & \multicolumn{1}{|c|}{\emph{MS .NET}} & \multicolumn{1}{|c|}{\emph{Mono}} & \multicolumn{1}{c}{\emph{MS .NET}} \\
275 \cline{2-5}
276 Temps & 39 s & 20 s & 48 s & 20 s \\
277 Mémoire utilisée & 7.0 MiB & 14 MiB & 15.2 MiB & 13.9 MiB \\
278 Taux \emph{CPU} & 1 x 100 \% & 1 x 100 \% & 1 x 100 \% & 1 x 100 \% \\
279 \end{tabular}
280
281
282 \section{Analyse de la sécurité de l'implémentation}
283
284 \subsection{Quelles sont les parties critiques du code et comment s'assure-t-on que ces parties soient correctement implémentées ?}
285
286 La génération des clefs \emph{AES} doit être faite avec un générateur cryptographique. Dans notre cas nous utilisons \emph{RSACryptoServiceProvider}\footnote{\rsacryptoserviceprovider}.
287
288 La mémoire correspondant aux clefs générées devrait être effacée. Dans notre cas si un attaquant a accès à la mémoire de notre programme, alors il a accès au contenu des fichiers à chiffrer : il n'y a donc pas de précautions prises en particulier à ce sujet.
289
290
291 \subsection{Quels sont les points faibles restants et quelles sont les possibilités de les corriger ?}
292
293 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é.
294
295
296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 \section{Conclusion}
298
299 [TODO]
300
301
302
303 \bibliographystyle{plain}
304 \bibliography{main}
305
306 \end{document}