let filenameKey = "filename"
let modificationTimeKey = "file-modification-time"
+ let internal (@@) a1 a2 = Array.append a1 a2
+
let generatKeysPair : Key * Key = Crypto.generateRSAKeysPair
let encryptFile (inputFilePath : string) (outputFilePath : string) (signaturePrivKey: Key) (cryptPubKey : Key) =
let keyAES, keyMAC, iv = Crypto.rand 32, Crypto.rand 32, Crypto.rand 16
let fileInfo = new FileInfo (inputFilePath)
- use inputStream = new FileStream (inputFilePath, FileMode.Open, FileAccess.Read)
+ use inputStream = fileInfo.OpenRead ()
use outputStream = new FileStream (outputFilePath, FileMode.Create, FileAccess.Write)
let writer = new BinaryWriter (outputStream)
- writer.Seek (32 + 256, SeekOrigin.Current) |> ignore // Skips mac and signature. They will be written later.
+ outputStream.Position <- 32L + 256L // Skips mac and signature. They will be written later.
- Crypto.encryptRSA cryptPubKey (Array.append keyAES <| Array.append keyMAC iv) |> writer.Write
+ Crypto.encryptRSA cryptPubKey (keyAES @@ keyMAC @@ iv) |> writer.Write
// Plaintext -> cryptoStream -> hmacStream -> cyphertext.
let hmacStream, hmac = Crypto.HMACStream keyMAC outputStream
// Write the signature.
Crypto.signRSA signaturePrivKey hmac.Hash |> writer.Write
+ // May raise one of the following error:
+ // * IntegrityError
+ // * SignatureMismatch
+ // * UnableToDecryptAESKeys
let decryptFile (sourceFilePath : string) (targetDirPath : string) (signaturePubKey: Key) (decryptPrivKey : Key) =
use inputStream = new FileStream (sourceFilePath, FileMode.Open, FileAccess.Read)
use reader = new BinaryReader (inputStream)
let decrypt () =
API.decryptFile cipherFilename "." keySigPub keyCryptPriv
- let writeByteToCipherFileAt byte position =
- using (new FileStream (cipherFilename, FileMode.Open, FileAccess.Write))
+ let incrementByteCipherFileAt position =
+ using (new FileStream (cipherFilename, FileMode.Open, FileAccess.ReadWrite))
(fun fs -> fs.Position <- position
- fs.Write ([| byte |], 0, 1))
+ let byte = fs.ReadByte () |> byte
+ fs.Position <- position
+ fs.Write ([| byte + 1uy |], 0, 1)) // Automatically modulo 256.
encrypt ()
File.Delete plainFilename
assert (File.ReadAllText plainFilename = fileContent)
printfn "== Altering the MAC..."
- writeByteToCipherFileAt 0uy 0L
+ incrementByteCipherFileAt 0L
try
decrypt ()
assert false
printfn "== Altering the signature..."
encrypt ()
- writeByteToCipherFileAt 0uy 32L
+ incrementByteCipherFileAt 32L
try
decrypt ()
assert false
printfn "== Altering the keys..."
encrypt ()
- writeByteToCipherFileAt 0uy (32L + 256L)
+ incrementByteCipherFileAt (32L + 256L)
try
decrypt ()
assert false
printfn "== Altering the cyphering..."
encrypt ()
- writeByteToCipherFileAt 0uy (32L + 256L + 256L)
+ incrementByteCipherFileAt (32L + 256L + 256L)
try
decrypt ()
assert false
\subsection{Comment s'assure-t-on que les données sont stockées de manière confidentielle ? En particulier ce qui concerne les méta-données}
-Les méta-données ainsi que les données sont chiffrées ensemble. Voir le format du container décrit ci après.
+Les méta-données ainsi que les données sont chiffrées ensemble. Voir le format du container décrit ci-après.
\subsection{Comment s'assure-t-on que les données stockées sont authentiques ? Quels sont les risques à prendre en compte ?}
\subsection{Utilisation}
-Il est possible de compiler la solution à l'aide de \emph{MonoDevelop}\footnote{\monodevelop}. Le script \emph{Bash} \texttt{labo2-fsharp/run\_tests.sh} permet de compiler la solution puis d'exécuter un certain nombre de tests.
+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.
À partir du dossier \texttt{labo2-fsharp} et après avoir compiler en \emph{release} la solution, voici ce qu'il est possible d'effectuer :
\subsection{Organisation du code}
-La \emph{ĺibrary} \emph{CryptoFile} est composé de trois fichiers :
+La \emph{ĺibrary} \emph{CryptoFile} est composée de trois fichiers :
\begin{itemize}
\item \emph{Types.fs} : Quelques types publics.
\subsection{Mesures de performance}
-Quelques mesures sur un fichier de 871 MiB.
+Quelques mesures sur un fichier de 871 MiB. Sous \emph{Linux} avec \emph{Mono} 3.10.0. Des résultats similaire ont été obtenus sous \emph{Windows 8} avec \emph{Visual Studio 2012}.
Chiffrement :
\subsection{Quelles sont les parties critiques du code et comment s'assure-t-on que ces parties soit correctement implémentées ?}
-La génération des clefs \emph{AES} doit être faite avec un générateur cryptographique. Dans notre cas nous utilisons \emph{System.Security.Cryptography.RSACryptoServiceProvider}\footnote{\rsacryptoserviceprovider}.
+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}.
La mémoire correspondant aux clefs générées devrait être effacé, 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 prise en particulier à ce sujet.
-\subsection{Quels sont les points-faibles restants et quelles sont les possibilités de les corriger ?}
+\subsection{Quels sont les points faibles restants et quelles sont les possibilités de les corriger ?}
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é.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Conclusion}
-% http://stephenhaunts.com/2013/03/04/cryptography-in-net-advanced-encryption-standard-aes/
-% http://stephenhaunts.com/2013/03/26/cryptography-in-net-rsa/
-% http://en.wikipedia.org/wiki/Digital_signature
-%\bibliographystyle{plain}
-%\bibliography{main}
+
+
+\bibliographystyle{plain}
+\bibliography{main}
\end{document}