module Labo2.Crypto open System.Security.Cryptography open System.IO type Key = string type Data = byte[] let rsaKeySize = 2048 let generate256Key : Key = null /// Generate a new RSA key pair: (public * private). let generateRSAKeysPair : Key * Key = use rsa = new RSACryptoServiceProvider (rsaKeySize) try rsa.ToXmlString false, rsa.ToXmlString true finally rsa.PersistKeyInCsp <- false let encryptRSA (publicKey : Key) (plaindata : Data) : Data = use rsa = new RSACryptoServiceProvider (rsaKeySize) try rsa.FromXmlString publicKey rsa.Encrypt (plaindata, false) // Uses PKCS#1 v1.5 padding. finally rsa.PersistKeyInCsp <- false let decryptRSA (privateKey : Key) (cipherdata : Data) : Data = use rsa = new RSACryptoServiceProvider (rsaKeySize) try rsa.FromXmlString privateKey rsa.Decrypt (cipherdata, false) // Uses PKCS#1 v1.5 padding. finally rsa.PersistKeyInCsp <- false /// Produces a signature from a given hash. let signRSA (privKey : Key) (sha256 : Data) : Data = use rsa = new RSACryptoServiceProvider (rsaKeySize) try rsa.FromXmlString privKey rsa.SignHash (sha256, CryptoConfig.MapNameToOID "SHA256") finally rsa.PersistKeyInCsp <- false /// Verify a signature against a given hash. let verifySignRSA (pubKey : Key) (sha256 : Data) (signature : Data) : bool = use rsa = new RSACryptoServiceProvider (rsaKeySize) try rsa.FromXmlString pubKey rsa.VerifyHash (sha256, CryptoConfig.MapNameToOID "SHA256", signature) finally rsa.PersistKeyInCsp <- false let decryptAES (key : Key) (inputStream : Stream) (outputStream : Stream) = () open System.Text let testRSA = lazy ( let kpub, kpriv = generateRSAKeysPair let plaintext = "Hello, World!" printfn "plaintext: %A" plaintext let cipherdata = encryptRSA kpub (Encoding.UTF8.GetBytes plaintext) printfn "cipherdata: (size: %A) %A" cipherdata.Length cipherdata let decryptedData = decryptRSA kpriv cipherdata let decryptedText = Encoding.UTF8.GetString decryptedData printfn "decryptedtext: %A" decryptedText assert (plaintext = decryptedText) printfn "testRSA OK" ) let testRSASignature = lazy ( let kpub, kpriv = generateRSAKeysPair let plaintext = "Hello, World!" let sha256 = new SHA256Managed () let signature = signRSA kpriv (sha256.ComputeHash (Encoding.UTF8.GetBytes plaintext)) assert verifySignRSA kpub (sha256.ComputeHash (Encoding.UTF8.GetBytes plaintext)) signature assert not (verifySignRSA kpub (sha256.ComputeHash (Encoding.UTF8.GetBytes "Hello!")) signature) printfn "testRSASignature OK" )