60f9c5f6562ad45cbc99edea260da500d7d5175b
3 // Some cryptography primitives specific to CryptoFile.
4 module internal Crypto =
7 open System.Security.Cryptography
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
20 /// Generate a new RSA key pair: (public * private).
21 let generateRSAKeysPair : Key * Key =
22 use rsa = new RSACryptoServiceProvider (rsaKeySize)
24 rsa.ToXmlString false, rsa.ToXmlString true
26 rsa.PersistKeyInCsp <- false
28 let encryptRSA (publicKey
: Key) (plaindata
: Data) : Data =
29 use rsa = new RSACryptoServiceProvider (rsaKeySize)
31 rsa.FromXmlString publicKey
32 rsa.Encrypt (plaindata
, false) // Uses PKCS#1 v1.5 padding.
34 rsa.PersistKeyInCsp <- false
36 let decryptRSA (privateKey
: Key) (cipherdata
: Data) : Data =
37 use rsa = new RSACryptoServiceProvider (rsaKeySize)
39 rsa.FromXmlString privateKey
40 rsa.Decrypt (cipherdata
, false) // Uses PKCS#1 v1.5 padding.
42 rsa.PersistKeyInCsp <- false
44 /// Produces a signature from a given hash.
45 let signRSA (privKey
: Key) (sha256
: Data) : Data =
46 use rsa = new RSACryptoServiceProvider (rsaKeySize)
48 rsa.FromXmlString privKey
49 rsa.SignHash (sha256
, CryptoConfig.MapNameToOID "SHA256")
51 rsa.PersistKeyInCsp <- false
53 /// Verify a signature against a given hash.
54 let verifySignRSA (pubKey
: Key) (sha256
: Data) (signature
: Data) : bool =
55 use rsa = new RSACryptoServiceProvider (rsaKeySize)
57 rsa.FromXmlString pubKey
58 rsa.VerifyHash (sha256
, CryptoConfig.MapNameToOID "SHA256", signature
)
60 rsa.PersistKeyInCsp <- false
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 ()
67 let encryptor = aes.CreateEncryptor (key
, iv
)
68 new CryptoStream (outputStream
, encryptor, CryptoStreamMode.Write)
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 ()
75 let decryptor = aes.CreateDecryptor (key
, iv
)
76 new CryptoStream (inputStream
, decryptor, CryptoStreamMode.Read)
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
84 let ComputeHMAC (key
: byte
[]) (inputStream
: Stream) : byte
[] =
85 assert (key
.Length = 32)
86 let hmac = new HMACSHA256 (key
)
87 hmac.ComputeHash inputStream