836d636af67b37e72fabf38ed5984659b518b75a
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 let HMACStream (key
: byte
[]) (outputStream
: Stream) : Stream * HMACSHA256 =
79 assert (key
.Length = 32)
80 let hmac = new HMACSHA256 (key
)
81 new CryptoStream (outputStream
, hmac, CryptoStreamMode.Write) :> Stream, hmac
83 (*type HMACStream (buffer: byte[], output: Stream) =
85 override this.CanRead with get () = false
86 override this.CanSeek with get () = false
87 override this.CanWrite with get () = true
88 override this.Length with get () = raise <| new NotSupportedException ()
89 override this.Position with get () = raise <| new NotSupportedException ()
90 and set _ = raise <| new NotSupportedException ()
91 override this.Flush () =
93 override this.Read (_: byte[], _: int, _: int) = raise <| new NotSupportedException ()*)