From fe03a7f9df6b8f4cf03e2399aeb68a7dc2605a67 Mon Sep 17 00:00:00 2001 From: Ummon Date: Fri, 7 Nov 2014 18:31:12 +0100 Subject: [PATCH] Code cleaning. --- lab1_rust/src/end_point.rs | 8 ++--- lab1_rust/src/main.rs | 6 ++-- lab1_rust/src/oracle_machine.rs | 6 ++-- lab1_rust/src/packet.rs | 22 ++++++------ rapport/main.bib | 7 ++++ rapport/main.tex | 63 +++++++++++++++++---------------- 6 files changed, 61 insertions(+), 51 deletions(-) diff --git a/lab1_rust/src/end_point.rs b/lab1_rust/src/end_point.rs index 51b55b8..128a017 100644 --- a/lab1_rust/src/end_point.rs +++ b/lab1_rust/src/end_point.rs @@ -118,7 +118,7 @@ impl Client { } } - /// Send some valid and not-valid packets to the server and check the result. + /// Sends some valid and not-valid packets to the server and check the result. /// For each test a new client is created. pub fn start_tests(address: &str, port: u16, variant: packet::Variant) { let execute = |f: &mut |&mut Client| -> bool| -> bool { @@ -269,7 +269,7 @@ impl EndPoint { println!("[{}] time: {}. {}", prefix, self.current_timestamp, s); } - /// Send a packet and wait for an answer synchronously. + /// Sends a packet and wait for an answer synchronously. fn send_with_result(&mut self, p: PacketType) -> IoResult { match self.send(p) { Err(e) => Err(e), @@ -277,8 +277,8 @@ impl EndPoint { } } - /// Send arbitrary data and wait for an answer synchronously. - /// Do not increment the current timestamp. + /// Sends arbitrary data and wait for an answer synchronously. + /// Doesn't increment the current timestamp. pub fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult { self.socket.set_timeout(DEFAULT_TIMEOUT); match self.socket.write(p) { diff --git a/lab1_rust/src/main.rs b/lab1_rust/src/main.rs index ea511be..dbaebea 100644 --- a/lab1_rust/src/main.rs +++ b/lab1_rust/src/main.rs @@ -29,14 +29,14 @@ fn do_oracle_attack(address: &str, variant: packet::Variant) { match oracle_machine::decipher(address, PORT, &xor_operand, &cipher_block, variant) { Some(ref deciphered) if deciphered.as_slice() == expected_plain_block => { - println!("The oracle machine has found the clear block!:"); + println!("The oracle machine has found the plain block!:"); println!(" Expected block: {}", expected_plain_block.to_vec()); println!(" Decrypted block: {}", deciphered) } Some(ref other) => - println!("The oracle machine hasn't found the clear block: {}", other), + println!("The oracle machine hasn't found the plain block: {}", other), _ => - println!("The oracle machine hasn't found the clear block"), + println!("The oracle machine hasn't found the plain block"), } } diff --git a/lab1_rust/src/oracle_machine.rs b/lab1_rust/src/oracle_machine.rs index 316f06e..dd0430d 100644 --- a/lab1_rust/src/oracle_machine.rs +++ b/lab1_rust/src/oracle_machine.rs @@ -6,7 +6,7 @@ use packet; use packet::{ Packet, Error }; use end_point::EndPoint; -/// Try to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port. +/// Tries to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port. /// May print some messages on stdout. pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cipher_block: &[u8, ..16], variant: packet::Variant) -> Option> { let mut end_point = EndPoint::new( @@ -20,7 +20,7 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip variant, ); - // See 'packet::Packet' documentation for a complete description about the binary packet structure. + // Sees 'packet::Packet' documentation for a complete description about the binary packet structure. let mut final_packet = [0u8, ..2 + 1 + 8 + 32 + 10]; final_packet[1] = (final_packet.len() as u8) - 2; // Data length. copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipher_block); @@ -40,7 +40,7 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip for v in range_inclusive(0u8, 255) { // For each values of the current byte. - // Compute and write timestamp. + // Computes and writes timestamp. current_timestamp += 2; { let mut timestamp_writer = io::BufWriter::new(final_packet.slice_mut(2 + 1, 2 + 1 + 8)); diff --git a/lab1_rust/src/packet.rs b/lab1_rust/src/packet.rs index c81fe20..8b02ccd 100644 --- a/lab1_rust/src/packet.rs +++ b/lab1_rust/src/packet.rs @@ -158,19 +158,19 @@ impl Packet { _ => () } - // Compute the MAC. It depends of the choosen variant. + // Computes the MAC. It depends of the choosen variant. let mac = crypto::compute_mac(data.slice_to(match variant { Weak => data_size, _ => data.len() })); - // Encrypt. + // Encrypts. let encrypted_data = match crypto::encrypt(data.as_slice(), iv_from_timestamp(self.timestamp).as_slice()) { Some(d) => d, _ => return Err(EncryptError) }; - // Write packet length. + // Writes packet length. try_write_io!(output.write_be_u16((encrypted_data.len() + FIXED_PACKET_SIZE) as u16)); - // Write packet type. + // Writes packet type. try_write_io!(output.write_u8( match self.t { Command(_) => 0x00, @@ -180,13 +180,13 @@ impl Packet { } )); - // Write timestamp. + // Writes timestamp. try_write_io!(output.write_be_u64(self.timestamp)); - // Write encrypted data. + // Writes encrypted data. try_write_io!(output.write(encrypted_data.as_slice())); - // Write the MAC. + // Writes the MAC. try_write_io!(output.write(mac)); Ok(()) @@ -199,7 +199,7 @@ impl Packet { let data_size = try_read_io!(input.read_be_u16()); - // Read and check the packet type. + // Reads and checks the packet type. let packet_type = try_read_io!(input.read_u8()); if ![0x00, 0xFF, 0x0A, 0x0B].iter().any(|p| *p == packet_type) { consume(input, data_size as uint - 1); @@ -217,7 +217,7 @@ impl Packet { _ => return Err(UnconsistentEncryptedSizeError) }; - // Read the MAC. + // Reads the MAC. let mut mac_read = [0u8, ..10]; if try_read_io!(input.read(mac_read)) != mac_read.len() { return Err(UnconsistentMACSizeError) @@ -225,7 +225,7 @@ impl Packet { match variant { Fixed if mac_read != crypto::compute_mac(data.as_slice()) => return Err(MACMismatchError), _ => () }; - // Control the size and the content of the padding then remove it. + // Controls the size and the content of the padding then removes it. if packet_type == 0x00 || packet_type == 0xFF { match data.last() { Some(&padding_size) => { @@ -267,7 +267,7 @@ impl Packet { } } -// Build an initialization vector: 64 * 0u8 + timestamp (128 bits). +// Builds an initialization vector: 64 * 0u8 + timestamp (128 bits). fn iv_from_timestamp(timestamp: u64) -> Vec { let mut iv = io::MemWriter::with_capacity(16); let _ = iv.write_be_u64(0u64); diff --git a/rapport/main.bib b/rapport/main.bib index 8c58aea..3a08b2e 100644 --- a/rapport/main.bib +++ b/rapport/main.bib @@ -6,6 +6,13 @@ url = "\url{http://cseweb.ucsd.edu/~mihir/papers/oem.html}" } +@article {modes-of-operation, + author = "Phillip Rogaway", + title = "Evaluation of Some Blockcipher Modes of Operation", + journal = "University of California", + year = "2011", +} + @misc {wiki-replay-attack, author = "Wikipedia", title = "Replay attack --- {W}ikipedia{,} The Free Encyclopedia", diff --git a/rapport/main.tex b/rapport/main.tex index 5e157a7..c1fd71e 100644 --- a/rapport/main.tex +++ b/rapport/main.tex @@ -23,7 +23,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Introduction} -Le but de ce laboratoire est d'expérimenter le chiffrement symétrique \emph{AES} ainsi que l'authentification par \emph{MAC}, de mettre en évidence des problèmes de sécurité liés à un protocole choisi propre et de montrer des solutions afin de corriger ces problèmes. +Le but de ce laboratoire est d'expérimenter le chiffrement symétrique \emph{AES} ainsi que la vérification de l'intégrité des données par \emph{MAC}, de mettre en évidence un problème de sécurité lié à un protocole choisi propre et de proposer une solution. Nous utiliseront \emph{AES-256} en mode \emph{CBC} pour chiffrer les données ainsi que \emph{HMAC-SHA256} pour l'authentification. @@ -33,9 +33,9 @@ Nous utiliseront \emph{AES-256} en mode \emph{CBC} pour chiffrer les données ai \subsection{Utilisation du programme} -Le code est écrit en langage Rust \footnote{\url{http://www.rust-lang.org}} et utilise le système de build \emph{Cargo} qui est livré en standard. Il est conseillé d'installer la version \emph{nightly} disponible ici : \url{http://www.rust-lang.org/install.html}. +Le code est écrit en langage \emph{Rust} \footnote{\url{http://www.rust-lang.org}} et utilise le système de build \emph{Cargo} qui est livré en standard. Il est conseillé d'utiliser la version \emph{nightly} disponible ici : \url{http://www.rust-lang.org/install.html}. -Pour construire et lancer l'application il faut se trouver dans le dossier contenant le fichier \emph{Cargo.toml} et lancer la commande suivante. +Pour construire et lancer l'application il faut se trouver dans le dossier contenant le fichier \emph{Cargo.toml} et lancer la commande suivante : \begin{lstlisting} $> cargo run -- @@ -47,7 +47,7 @@ Où \emph{} peut valoir : \item \emph{genkey} : génère une clef de 256 bits. Utilisé initialement pour définir la clef d'authentification $K_{a}$ et la clef de chiffrement $K_{c}$ ; \item \emph{tests} : effectue un certain nombre de tests pour vérifier le comportement du serveur vis-à-vis du protocole ; \item \emph{oracle-weak} : effectue une attaque sur la première version du serveur ; - \item \emph{oracle-fixed} : effectue une attaque sur la version corrigé du serveur. + \item \emph{oracle-fixed} : effectue une attaque sur la version corrigée du serveur. \end{itemize} @@ -64,17 +64,16 @@ Le code est découpé en quatre modules : \subsection{Tests du protocole} \begin{sloppypar} -Un certain nombre de tests sont implémenté dans la fonction \texttt{end\_point::Client::start\_tests(..)}. Il est possible de les exécuter à l'aide de la commande suivante. +Un certain nombre de tests sont implémentés dans la fonction \texttt{end\_point::Client::start\_tests(..)}. Il est possible de les exécuter à l'aide de la commande suivante. \end{sloppypar} \begin{lstlisting} $> cargo run -- tests \end{lstlisting} -La sortie de cette commande est la suivante. +La sortie de cette commande est la suivante : \begin{lstlisting}[breaklines, basicstyle=\small] -$> cargo run -- tests Compiling lab1_rust v0.0.1 (file:///home/gburri/Documents/Master/ICR/lab1/lab1_rust) Running `target/lab1_rust tests` Starting server on [::1]:4221... @@ -122,7 +121,7 @@ All tests passed \end{lstlisting} -\subsection{Quelle est la stratégie recommandée en pratique parmi les trois listées ci après ?} +\subsection{Quelle est la stratégie recommandée en pratique parmi les trois listées ci-après ?} \begin{itemize} \item \emph{MAC-and-Encrypt} : $Enc(M)|MAC(M)$ ; @@ -130,35 +129,35 @@ All tests passed \item \emph{Encrypt-then-MAC} : $Enc(M)|MAC(Enc(M))$. \end{itemize} -D'après \cite{wiki-authentication-encryption} la stratégie \emph{Encrypt-then-MAC} est la plus sûre dans le cadre de chiffrage authentifié. L'article de \emph{M. Bellare and C. Namprempre} \cite{authenticated-encryption-bellare-namprempre} évalue ces trois stratégies. +D'après \cite{wiki-authentication-encryption}, la stratégie \emph{Encrypt-then-MAC} est la plus sûre dans le cadre du chiffrage authentifié. L'article de \emph{M. Bellare and C. Namprempre} \cite{authenticated-encryption-bellare-namprempre} évalue ces trois stratégies. \subsubsection{Quelle stratégie est utilisée par \emph{TLS} ?} -\emph{TSL} utilise la deuxième version (\emph{MAC-then-Encrypt}). À noté que le \emph{MAC} est optionnel. +\emph{TSL} utilise la deuxième version (\emph{MAC-then-Encrypt}). À noter que le \emph{MAC} est optionnel. Une proposition \footnote{https://tools.ietf.org/html/draft-ietf-tls-encrypt-then-mac-02} existe afin d'utiliser du \textit{Encrypt-then-MAC} pour \emph{TSL}. \subsubsection{Quelle stratégie est utilisée par \emph{SSH} ?} -\emph{SSH} utilise la même méthode utilisée dans ce laboratoire, c'est à dire la première : \emph{MAC-and-Encrypt}. +\emph{SSH} utilise la même méthode que celle utilisée dans ce laboratoire, c'est-à-dire \emph{MAC-and-Encrypt}. \subsection{Quel est le rôle du timestamp en terme de sécurité ?} -Permet de minimiser certaines attaques comme l'attaque par rejeu (\emph{replay attack})\cite{wiki-replay-attack} où un attaquant réutilise tel-quel tout ou une partie d'un message intercepté au préalable. +Il permet de minimiser certaines attaques comme l'attaque par rejeu (\emph{replay attack})\cite{wiki-replay-attack} où un attaquant réutilise tel-quel tout ou une partie d'un message intercepté au préalable. -Dans notre cas un attaquant ne pourra pas rejouer une commande tel quelle, elle serait rejetée par le serveur ayant un \emph{timestamp} supérieur. Si l'attaquant essaie de renvoyer un paquet avec un timestamp modifié, alors les données décodées ne seront plus validées par la \emph{MAC} car le vecteur d'initialisation utilisé (\emph{IV}) lors du déchiffrement est composé en partie par le \emph{timestamp}. +Dans notre cas un attaquant ne pourra pas rejouer une commande telle quelle, car elle serait rejetée par le serveur ayant un \emph{timestamp} supérieur. Si l'attaquant essaie de renvoyer un paquet avec un timestamp modifié, alors les données décodées ne seront plus validées par le \emph{MAC} car le vecteur d'initialisation utilisé (\emph{IV}) lors du déchiffrement est composé en partie par le \emph{timestamp}. \subsection{Y a-t-il un moyen d'effectuer une attaque de type \emph{denial-of-service} sur notre dispositif ?} -Via une \emph{replay attack} en modifiant le \emph{timestamp} pour qu'il soit valide le dispositif va devoir déchiffrer les données puis calculer le \emph{MAC} avant de se rendre compte que le paquet est invalide et envoyer une réponse qui sera chiffrée et authentifiée. Dans ce cas on peut faire travailler énormément le dispositif en lui envoyant le plus de paquet à déchiffrer que le permet le débit du moyen de communication utilisé. Cela peut amener le dispositif a être surchargé. +Via une \emph{replay attack} en modifiant le \emph{timestamp} pour qu'il soit valide, le dispositif va devoir déchiffrer les données puis calculer le \emph{MAC} avant de se rendre compte que le paquet est invalide et envoyer une réponse qui sera chiffrée et authentifiée. Dans ce cas on peut faire travailler énormément le dispositif en lui envoyant autant de paquets à déchiffrer que le permet le débit du moyen de communication utilisé. Cela peut amener le dispositif à être surchargé. \subsection{À la place d'utiliser un \emph{IV} aléatoire, le mode \emph{CBC} implémente une approche basée sur un \emph{nonce}. Que peut-on dire de sa sécurité ?} - +Cet article de \emph{P. Rogaway}\cite{modes-of-operation} suggère d'éviter de suivre le standard qui consiste à chiffrer le nonce avec la même clef utilisée pour les données. \subsection{Remarques concernant la sécurité de notre protocole} @@ -171,7 +170,7 @@ A priori nous n'avons pas choisi la stratégie la plus recommandée en terme de \subsection{Historique de l'attaque par oracle à l'aide du remplissage} -L'attaque original a été publié en 2002 par \emph{Serge Vaudenay}. En 2010, cette attaque a été mise en pratique contre plusieurs frameworks web tel que \emph{JavaServer Faces}, \emph{Ruby on Rails} et \emph{ASP.NET}. En 2012, il a été montré qu'elle est efficace contre certain appareils hardware. +L'attaque originelle a été publiée en 2002 par \emph{Serge Vaudenay}. En 2010, cette attaque a été mise en pratique contre plusieurs frameworks web tels que \emph{JavaServer Faces}, \emph{Ruby on Rails} et \emph{ASP.NET}. En 2012, il a été montré qu'elle était efficace contre certain appareils hardware. Il existe une nouvelle variante, publiée en 2013, nommée \emph{the Lucky Thirteen attack}, permettant d'attaquer des implémentations ayant été corrigées. En février 2013, les personnes en charge des implémentations de \emph{TLS} travaillaient à la réalisation d'un correctif à cette attaque. @@ -183,9 +182,9 @@ Cette section est largement inspirée de l'article de \emph{Wikipedia} sur la \e Le but est de faire décoder par un oracle tout ou une partie d'un message chiffré intercepté. Le décryptage se fait par bloc de 16 octets et nécessite le bloc chiffré le précédant ou l'\emph{IV} dans le cas du premier bloc. Pour notre test nous partons du principe que l'attaquant a intercepté un paquet chiffré, qu'il en a compris la structure et qu'il a deviné que l'\emph{IV} correspondait au \emph{timestamp}. -Nous utilisons une attaque basé sur l'information renvoyé par l'oracle concernant la présence d'un bourrage valide. D'après le protocole un \emph{MAC} est calculé à partir des données non-bourrées puis le bourrage est ajouté pour obtenir une taille multiple de 16 et finalement les données et le bourrage sont chiffrés. Lors du traitement par l'oracle, les données sont d'abord déchiffrées puis le bourrage est contrôlé, s'il n'est pas valide un paquet d'erreur et renvoyé au client (\emph{CryptError}). Si le bourrage est correct alors celui ci est retiré et les données restantes sont authentifiée à l'aide de la \emph{MAC}, si l'authentification échoue alors un paquet d'erreur et renvoyé au client (\emph{AuthError}). +Nous utilisons une attaque basée sur l'information renvoyée par l'oracle concernant la présence d'un bourrage valide. D'après le protocole un \emph{MAC} est calculé à partir des données non-bourrées, puis le bourrage est ajouté pour obtenir une taille multiple de 16, et finalement les données et le bourrage sont chiffrés. Lors du traitement par l'oracle, les données sont d'abord déchiffrées puis le bourrage est contrôlé. S'il n'est pas valide un paquet d'erreur est renvoyé au client (\emph{CryptError}). Si le bourrage est correct, alors celui-ci est retiré et les données restantes sont authentifiées à l'aide du \emph{MAC}. Si l'authentification échoue alors un paquet d'erreur est renvoyé au client (\emph{AuthError}). -La valeur des octets du bourrage correspond à sa taille, par exemple un bourrage de longueur trois est représenté par \emph{[0x03, 0x03, 0x03]}. Si les données avant bourrage sont déjà multiple de 16 alors un bourrage de longueur 16 est ajouté de sorte qu'un bourrage soit toujours présent. +La valeur des octets du bourrage correspond à sa taille, par exemple un bourrage de longueur trois est représenté par \emph{[0x03, 0x03, 0x03]}. Si les données avant bourrage sont déjà multiple de 16, alors un bourrage de longueur 16 est ajouté de sorte qu'un bourrage soit toujours présent. \begin{figure} \begin{center} @@ -195,13 +194,13 @@ La valeur des octets du bourrage correspond à sa taille, par exemple un bourrag \end{center} \end{figure} -La figure \ref{diagramme_AES-CBC} illustre la structure de l'attaque. \emph{IV} et \emph{D} n'ont pas d'importance dans notre cas. \emph{X} est le bloc à décrypter, \emph{X'} est le bloc à décrypter après avoir été décodé par \emph{AES} mais avant d'avoir été \flqq xoré \frqq par \emph{F}. \emph{F} correspond à un bloc qui sera forgé par nos soins durant le décryptage de \emph{X}. De plus \emph{C}, qui n'est pas illustré sur le schéma, correspond au bloc précédent \emph{X} ou à l'\emph{IV} si \emph{X} est le premier bloc et \emph{R} correspond au message décrypté. +La figure \ref{diagramme_AES-CBC} illustre la structure de l'attaque. \emph{IV} et \emph{D} n'ont pas d'importance dans notre cas. \emph{X} est le bloc à décrypter (\emph{ciphertext}), \emph{X'} est le bloc à décrypter après avoir été décodé par \emph{AES} mais avant d'avoir été \og xoré \fg{} par \emph{F}. \emph{F} correspond à un bloc qui sera forgé par nos soins durant le décryptage de \emph{X}. De plus \emph{C}, qui n'est pas illustré sur le schéma, correspond au bloc précédent \emph{X} ou à l'\emph{IV} si \emph{X} est le premier bloc et \emph{R} correspond au message décrypté (\emph{plaintext}). -dans un premier temps nous allons chercher le premier octet $b$ de $F$ noté $F_{1}$ en itérant celui ci de 0 à 255. Pour chaque itération un paquet de commande est envoyé à l'oracle comprenant en guise de données chiffrée $F + X$, le paquet d'erreur renvoyé va nous indiquer si le bourrage est correct (\emph{AuthError}) ou s'il ne l'est pas (\emph{CryptError}). Pour le premier octet nous allons chercher le bourrage \emph{[0x01]}, pour le deuxième le bourrage \emph{[0x02, 0x02]} et ainsi de suite jusqu'à l'octet 16. +Dans un premier temps nous allons chercher le premier octet $b$ de $F$ noté $F_{1}$ en itérant celui ci de 0 à 255. Pour chaque itération un paquet de commande est envoyé à l'oracle comprenant en guise de données chiffrées : $F + X$. Le paquet d'erreur renvoyé va nous indiquer si le bourrage est correct (\emph{AuthError}) ou s'il ne l'est pas (\emph{CryptError}). Pour le premier octet nous allons chercher le bourrage \emph{[0x01]}, pour le deuxième le bourrage \emph{[0x02, 0x02]} et ainsi de suite jusqu'à l'octet 16. -Dès qu'un paquet d'erreur \emph{AuthError} est reçu alors nous pouvons calculer $X'_{1} = F_{1} \oplus b$ puis le premier octet de notre message décrypté $R_{1} = X'_{1} \oplus C_{1}$. Avant de passer à l'octet suivant $b' = b + 1$ il faut s'assurer que les $b$ premiers octets de \emph{E} vaudront bien $b'$ lors du décryptage par l'oracle, pour ce faire on met à jour \emph{F} comme ceci : $\forall i \in [1, \ldots, b], F_{i} = b' \oplus X_{i}$. +Dès qu'un paquet d'erreur \emph{AuthError} est reçu alors nous pouvons calculer $X'_{1} = F_{1} \oplus b$ puis le premier octet de notre message décrypté $R_{1} = X'_{1} \oplus C_{1}$. Avant de passer à l'octet suivant $b' = b + 1$ il faut s'assurer que les $b$ premiers octets de \emph{E} vaudront bien $b'$ lors du décryptage par l'oracle. Pour ce faire on met à jour \emph{F} comme ceci : $\forall i \in [1, \ldots, b], F_{i} = b' \oplus X_{i}$. -Une subtilité existe pour la recherche du premier octet, il est possible que le paquet d'erreur \emph{AuthError} correspond, avec une faible probabilité, à un autre bourrage que \emph{[0x01]}. Pour prévenir ce cas il faut, pour ce premier octet, envoyer un paquet de commande pour toutes les valeurs de $F_{1}$ et compter le nombre de paquet d'erreur \emph{AuthError} reçu. Si ce nombre est égal à 1 alors on peut passer à $b'$, sinon il faut recommencer en modifiant $F_{2} = (F_{2} + 1) mod 256$. +Une subtilité existe pour la recherche du premier octet : il est possible que le paquet d'erreur \emph{AuthError} corresponde, avec une faible probabilité, à un autre bourrage que \emph{[0x01]}. Pour prévenir ce cas il faut, pour ce premier octet, envoyer un paquet de commande pour toutes les valeurs de $F_{1}$ et compter le nombre de paquets d'erreur \emph{AuthError} reçus. Si ce nombre est égal à 1 alors on peut passer à $b'$, sinon il faut recommencer en modifiant $F_{2} = (F_{2} + 1)\, mod\, 256$. Le code correspondant à cette attaque peut être exécuté par la commande suivante : @@ -209,12 +208,20 @@ Le code correspondant à cette attaque peut être exécuté par la commande suiv $> cargo run --release -- oracle-weak \end{lstlisting} +La sortie est la suivante : + +\begin{lstlisting}[breaklines, basicstyle=\small] +The oracle machine has found the plain block!: + Expected block: [242, 93, 12, 22, 8, 164, 4, 77, 200, 120, 189, 71, 75, 189, 2, 2] + Decrypted block: [242, 93, 12, 22, 8, 164, 4, 77, 200, 120, 189, 71, 75, 189, 2, 2] +\end{lstlisting} + -\subsection{Calcul de la complexité moyenne de l'attaque en terme de nombre de requête effectué auprès de l'oracle} +\subsection{Calcul de la complexité moyenne de l'attaque en terme de nombre de requêtes effectuées auprès de l'oracle} Sans prendre en compte la particularité du premier octet illustré à la section précédente, la complexité moyenne pour le décryptage d'un bloc de 16 octets est de $16 * 256 / 2 = 2048$ requêtes. -Dans l'exemple présenté dans le code, le nombre de requête est de 2099. La durée d'exécution est de ~180 ms, cette relative longue durée est certainement dû à un overhead engendré par les couches réseau \emph{TCP/IP}. +Dans l'exemple présenté dans le code, le nombre de requêtes est de 2099. La durée d'exécution est de ~180 ms, cette relative longue durée est certainement due à un overhead engendré par les couches réseau \emph{TCP/IP}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -222,7 +229,7 @@ Dans l'exemple présenté dans le code, le nombre de requête est de 2099. La du \subsection{Description} -Le correctif proposé consiste à authentifier également le bourrage et non-plus que les données. Cela a pour conséquence de vérifier en premier l'authenticité du contenu avant de procéder à la validité du padding. Les deux messages d'erreur, \emph{CryptError} et \emph{AuthError}, font toujours partis du protocole. +Le correctif proposé consiste à authentifier également le bourrage et non plus que les données. Cela a pour conséquence de vérifier en premier l'authenticité du contenu avant de procéder à la validité du padding. Les deux messages d'erreur, \emph{CryptError} et \emph{AuthError}, font toujours parties du protocole. Le code correspondant à ce correctif peut être exécuté par la commande suivante : @@ -234,11 +241,7 @@ $> cargo run --release -- oracle-fixed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Conclusion} -TODO - - - - +Ce laboratoire a permis de mettre en évidence une attaque par \emph{padding-oracle} sur un protocole utilisant des normes de sécurité standards et éprouvées telles que \emph{AES} en mode \emph{CBC}, une authentification par \emph{HMAC-SHA256} et la stratégie \emph{MAC-and-Encrypt}. Une solution a ensuite été proposée et testée face à l'attaque précédemment citée. \bibliographystyle{plain} -- 2.45.2