Decrypting should work.
[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
6 open System.IO
7 open System.Security.Cryptography
8
9 type Data = byte[]
10
11 let rsaKeySize = 2048
12
13 /// Returns a cryptographically strong sequence of bytes.
14 let rand size : byte[] =
15 let result = Array.zeroCreate size
16 let generator = new RNGCryptoServiceProvider ()
17 generator.GetBytes result
18 result
19
20 /// Generate a new RSA key pair: (public * private).
21 let generateRSAKeysPair : Key * Key =
22 use rsa = new RSACryptoServiceProvider (rsaKeySize)
23 try
24 rsa.ToXmlString false, rsa.ToXmlString true
25 finally
26 rsa.PersistKeyInCsp <- false
27
28 let encryptRSA (publicKey: Key) (plaindata: Data) : Data =
29 use rsa = new RSACryptoServiceProvider (rsaKeySize)
30 try
31 rsa.FromXmlString publicKey
32 rsa.Encrypt (plaindata, false) // Uses PKCS#1 v1.5 padding.
33 finally
34 rsa.PersistKeyInCsp <- false
35
36 let decryptRSA (privateKey: Key) (cipherdata: Data) : Data =
37 use rsa = new RSACryptoServiceProvider (rsaKeySize)
38 try
39 rsa.FromXmlString privateKey
40 rsa.Decrypt (cipherdata, false) // Uses PKCS#1 v1.5 padding.
41 finally
42 rsa.PersistKeyInCsp <- false
43
44 /// Produces a signature from a given hash.
45 let signRSA (privKey: Key) (sha256: Data) : Data =
46 use rsa = new RSACryptoServiceProvider (rsaKeySize)
47 try
48 rsa.FromXmlString privKey
49 rsa.SignHash (sha256, CryptoConfig.MapNameToOID "SHA256")
50 finally
51 rsa.PersistKeyInCsp <- false
52
53 /// Verify a signature against a given hash.
54 let verifySignRSA (pubKey: Key) (sha256: Data) (signature: Data) : bool =
55 use rsa = new RSACryptoServiceProvider (rsaKeySize)
56 try
57 rsa.FromXmlString pubKey
58 rsa.VerifyHash (sha256, CryptoConfig.MapNameToOID "SHA256", signature)
59 finally
60 rsa.PersistKeyInCsp <- false
61
62 /// Returns an encrypted output stream.
63 let encryptAES (key: byte[]) (iv: byte[]) (outputStream: Stream) : CryptoStream =
64 assert (key.Length = 32 && iv.Length = 16)
65 use aes = new AesManaged ()
66 aes.KeySize <- 256
67 let encryptor = aes.CreateEncryptor (key, iv)
68 new CryptoStream (outputStream, encryptor, CryptoStreamMode.Write)
69
70 /// Returns a decrypted input stream.
71 let decryptAES (key: byte[]) (iv: byte[]) (inputStream: Stream) : CryptoStream =
72 assert (key.Length = 32 && iv.Length = 16)
73 use aes = new AesManaged ()
74 aes.KeySize <- 256
75 let decryptor = aes.CreateDecryptor (key, iv)
76 new CryptoStream (inputStream, decryptor, CryptoStreamMode.Read)
77
78 // Create a stream to compute the HMAC-SHA256 against all data being written.
79 let HMACStream (key: byte[]) (outputStream: Stream) : Stream * HMACSHA256 =
80 assert (key.Length = 32)
81 let hmac = new HMACSHA256 (key)
82 new CryptoStream (outputStream, hmac, CryptoStreamMode.Write) :> Stream, hmac
83
84 let ComputeHMAC (key: byte[]) (inputStream: Stream) : byte[] =
85 assert (key.Length = 32)
86 let hmac = new HMACSHA256 (key)
87 hmac.ComputeHash inputStream