Put the API in an seperate library assembly and create an assembly for testing.
[crypto_lab2.git] / labo2-fsharp / CryptoFile / Crypto.fs
1 namespace CryptoFile
2
3 // Some cryptography primitives specific to CryptoFile.
4 module internal Crypto =
5 open System.Security.Cryptography
6 open System.IO
7
8 type Data = byte[]
9
10 let rsaKeySize = 2048
11
12 /// Returns a cryptographically strong sequence of bytes.
13 let rand size : byte[] =
14 let result = Array.zeroCreate size
15 let generator = new RNGCryptoServiceProvider ()
16 generator.GetBytes result
17 result
18
19 /// Generate a new RSA key pair: (public * private).
20 let generateRSAKeysPair : Key * Key =
21 use rsa = new RSACryptoServiceProvider (rsaKeySize)
22 try
23 rsa.ToXmlString false, rsa.ToXmlString true
24 finally
25 rsa.PersistKeyInCsp <- false
26
27 let encryptRSA (publicKey : Key) (plaindata : Data) : Data =
28 use rsa = new RSACryptoServiceProvider (rsaKeySize)
29 try
30 rsa.FromXmlString publicKey
31 rsa.Encrypt (plaindata, false) // Uses PKCS#1 v1.5 padding.
32 finally
33 rsa.PersistKeyInCsp <- false
34
35 let decryptRSA (privateKey : Key) (cipherdata : Data) : Data =
36 use rsa = new RSACryptoServiceProvider (rsaKeySize)
37 try
38 rsa.FromXmlString privateKey
39 rsa.Decrypt (cipherdata, false) // Uses PKCS#1 v1.5 padding.
40 finally
41 rsa.PersistKeyInCsp <- false
42
43 /// Produces a signature from a given hash.
44 let signRSA (privKey : Key) (sha256 : Data) : Data =
45 use rsa = new RSACryptoServiceProvider (rsaKeySize)
46 try
47 rsa.FromXmlString privKey
48 rsa.SignHash (sha256, CryptoConfig.MapNameToOID "SHA256")
49 finally
50 rsa.PersistKeyInCsp <- false
51
52 /// Verify a signature against a given hash.
53 let verifySignRSA (pubKey : Key) (sha256 : Data) (signature : Data) : bool =
54 use rsa = new RSACryptoServiceProvider (rsaKeySize)
55 try
56 rsa.FromXmlString pubKey
57 rsa.VerifyHash (sha256, CryptoConfig.MapNameToOID "SHA256", signature)
58 finally
59 rsa.PersistKeyInCsp <- false
60
61 /// Returns an encrypted output stream.
62 let encryptAES (key : byte[]) (iv : byte[]) (outputStream : Stream) : Stream =
63 assert (key.Length = 32 && iv.Length = 16)
64 use aes = new AesManaged ()
65 aes.KeySize <- 256
66 let encryptor = aes.CreateEncryptor (key, iv)
67 new CryptoStream (outputStream, encryptor, CryptoStreamMode.Write) :> Stream
68
69 /// Returns a decrypted input stream.
70 let decryptAES (key : byte[]) (iv : byte[]) (inputStream : Stream) : Stream =
71 assert (key.Length = 32 && iv.Length = 16)
72 use aes = new AesManaged ()
73 aes.KeySize <- 256
74 let decryptor = aes.CreateDecryptor (key, iv)
75 new CryptoStream (inputStream, decryptor, CryptoStreamMode.Read) :> Stream