Skip to content

Instantly share code, notes, and snippets.

@giuliohome
Created October 14, 2024 16:51
Show Gist options
  • Save giuliohome/b564c3283676599af71222ad2b75b675 to your computer and use it in GitHub Desktop.
Save giuliohome/b564c3283676599af71222ad2b75b675 to your computer and use it in GitHub Desktop.
F# Crypto AES equivalent of Golang https://pkg.go.dev/crypto/cipher#example-NewGCM-Encrypt
open System
open System.Security.Cryptography
open System.Text
type EncryptionInput = {key: string; plainText: string}
type B64EncryptionOuput = {cipherText: byte array; tag: byte array; nonce: byte array}
module myCrypt =
let decrypt (encrypted: B64EncryptionOuput) (key: string) : string =
let key = Encoding.UTF8.GetBytes(key)
let aesAlg : AesGcm = new AesGcm(key, key.Length)
let plainText : byte[] = Array.zeroCreate encrypted.cipherText.Length
aesAlg.Decrypt(
encrypted.nonce,
encrypted.cipherText,
encrypted.tag,
plainText)
Encoding.UTF8.GetString (plainText)
let encrypt (input: EncryptionInput) (debug: bool) : B64EncryptionOuput =
let key = Encoding.UTF8.GetBytes(input.key) // e.g. "1234567812345678"
let aesAlg : AesGcm = new AesGcm(key, key.Length)
let plainText = Encoding.UTF8.GetBytes(input.plainText)
let cipherText : byte[] = Array.zeroCreate plainText.Length
let nonce: byte[] = Array.zeroCreate 12
let tag: byte[] = Array.zeroCreate 16
RandomNumberGenerator.Fill(nonce)
aesAlg.Encrypt( nonce, plainText, cipherText, tag)
if debug then
printfn "Converted to base 64 encrypted text: %s \ntag: %s, nonce: %s"
( Convert.ToBase64String (cipherText) )
( Convert.ToBase64String (tag) )
( Convert.ToBase64String (nonce) )
let decrypted : byte[] = Array.zeroCreate cipherText.Length
aesAlg.Decrypt(nonce, cipherText, tag, decrypted)
printfn "Double check the decrypted text now: %s"
( Encoding.UTF8.GetString (decrypted) )
printfn "script ends"
{
cipherText = cipherText
nonce = nonce
tag = tag
}
// let input : myscript.EncryptionInput = { key = "1234567890123456"; plainText = "Here we go!@@@###§§§" };;
// let output = myscript.myCrypt.encrypt input false;;
// myscript.myCrypt.decrypt output input.key;;
let sample () =
printfn "script starts"
let a = [1..3]
let doubled = a |> List.map (fun x -> x * 2)
printfn "Doubled list: %A" doubled
let fileDecrypt (inputFile: string) (secret: string) : string =
let encrypted : byte[] = IO.File.ReadAllBytes(inputFile)
let nonce = encrypted[0 .. 12 - 1]
let cipherText = encrypted[12 .. encrypted.Length - 16 - 1]
let tag = encrypted[encrypted.Length - 16 .. encrypted.Length - 1]
decrypt {tag = tag; nonce = nonce; cipherText= cipherText } secret
type FileEncrypt = {inputFile: string; secret: string; outputFile: string}
let fileEncrypt (files: FileEncrypt) =
let plainText = IO.File.ReadAllBytes(files.inputFile)
let output : B64EncryptionOuput =
encrypt {key = files.secret; plainText = Encoding.UTF8.GetString(plainText) } false
let outBuffer : byte[] = Array.zeroCreate <| 12 + 16 + output.cipherText.Length
Buffer.BlockCopy(output.nonce, 0, outBuffer, 0, 12)
Buffer.BlockCopy(output.cipherText, 0, outBuffer, 12, output.cipherText.Length)
Buffer.BlockCopy(output.tag, 0, outBuffer, 12 + output.cipherText.Length, 16)
IO.File.WriteAllBytes(files.outputFile, outBuffer)
// myscript.myCrypt.fileEncrypt { inputFile = @"C:\Dati\fsharp.txt"; outputFile = @"C:\Dati\fsharp.giulio"; secret = "1234567890123456"}
// myscript.myCrypt.fileDecrypt @"C:\Dati\fsharp.giulio" "1234567890123456"
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment