Feather.Cryptography 2.3.0

dotnet add package Feather.Cryptography --version 2.3.0
                    
NuGet\Install-Package Feather.Cryptography -Version 2.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Feather.Cryptography" Version="2.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Feather.Cryptography" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Feather.Cryptography" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Feather.Cryptography --version 2.3.0
                    
#r "nuget: Feather.Cryptography, 2.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Feather.Cryptography@2.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Feather.Cryptography&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Feather.Cryptography&version=2.3.0
                    
Install as a Cake Tool

<img src="https://github.com/FeatherTools/.github/blob/main/profile/feather-logo-200.png" alt="FeatherTools Logo" width="100" height="100"> Cryptography

NuGet NuGet Downloads Checks

Library with a predefined use-cases for encryption, decryption and hashing.

Install

paket add Feather.Cryptography

Usage

Encoding

open Feather.Cryptography.Encode

// String to bytes and back
let text = "Hello, World!"
let bytes = stringToBytes text
let decoded = bytesToString bytes

// Base64 encoding
let encoded = Base64.encodeString "Hello, World!"
let decoded = Base64.decodeString encoded

// Base64 URL-safe encoding (for JWTs, URLs)
let base64Url =
    "Hello, World!"
    |> Base64.encodeString
    |> Base64.toBase64Url

let original =
    base64Url
    |> Base64.fromBase64Url
    |> Base64.decodeString

Hashing

open Feather.Cryptography.Hash

// SHA256 hex hash
let hash = SHA256.sha256Hex "hello world"
// Result: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

// CRC32 checksum
let checksum = Crc32.crc32OfString "hello world"
// Result: "d4a1185"

// SHA256 of bytes
let dataBytes = "hello world"B
let hashBytes = SHA256.sha256 dataBytes

RSA Encryption

open Feather.Cryptography.Cryptography

// Generate RSA key pair
let privateKey, publicKey = RSA256.createKeyPair()

// Encrypt data with public key
let plaintext = "Secret message"B
let encrypted = RSA256.encrypt publicKey plaintext

// Decrypt with private key
let decrypted = RSA256.decrypt privateKey encrypted

AES-GCM Encryption

open Feather.Cryptography.Cryptography

// Generate a data encryption key (DEK)
let dek = AES256GCM.generateKey()

// Encrypt without additional authenticated data (AAD)
let plaintext = "Sensitive data"B
let iv, ciphertext, tag = AES256GCM.encrypt dek None plaintext

// Decrypt
let decrypted = AES256GCM.decrypt dek iv ciphertext tag None

// Encrypt with AAD (authenticated but not encrypted metadata)
let metadata = AAD "document-id-123"B
let iv2, ciphertext2, tag2 = AES256GCM.encrypt dek (Some metadata) plaintext

// Decrypt with AAD
let decrypted2 = AES256GCM.decrypt dek iv2 ciphertext2 tag2 (Some metadata)

Symmetric Encryption

Simple encrypt/decrypt with a single secret string. Works with secrets from AWS Secrets Manager, CDK, or generated locally.

open Feather.Cryptography.Cryptography

// Generate a strong random secret
let secret = Symmetric.generateSecret()
// e.g. "dGhpcyBpcyBhIDMyLWJ5dGUga2V5ISEhISEhISEhIS0"

// Or use a secret stored externally (AWS Secrets Manager, CDK, etc.)
let secret = "my-secret-from-aws-secrets-manager"

// Encrypt
let ciphertext = Symmetric.encrypt secret "Hello, symmetric world!"
// Returns a base64url string: nonce ++ ciphertext ++ auth tag

// Decrypt
match Symmetric.decrypt secret ciphertext with
| Ok plaintext -> printfn "Decrypted: %s" plaintext
| Error msg    -> printfn "Failed: %s" msg

Envelope Encryption

Envelope encryption combines symmetric and asymmetric encryption: data is encrypted with a DEK (fast AES-GCM), then the DEK is encrypted with a master key (KEK) (RSA or vault service).

open Feather.Cryptography.Cryptography
open Feather.ErrorHandling

// Setup: Generate RSA keys or use a vault service
let privateKey, publicKey = RSA256.createKeyPair()

// Define how to encrypt the DEK (e.g., with RSA or vault)
let encryptDEK (DEK dek) = asyncResult {
    return RSA256.encrypt publicKey dek
}

// Define how to decrypt the DEK
let decryptDEK encryptedDek = asyncResult {
    let dekBytes = RSA256.decrypt privateKey encryptedDek
    return DEK dekBytes
}

// Encrypt data
let plaintext = "Top secret data"B
let envelope =
    EncryptedEnvelope.encrypt encryptDEK None plaintext
    |> AsyncResult.runSynchronously
    |> Result.orFail

// The envelope contains:
// - Version and Algorithm metadata
// - IV (initialization vector)
// - Ciphertext (encrypted data)
// - Tag (authentication tag)
// - DEK (encrypted data encryption key)
// - Optional AAD (additional authenticated data)

// Decrypt data
let decrypted =
    EncryptedEnvelope.decrypt decryptDEK envelope
    |> AsyncResult.runSynchronously
    |> Result.orFail

// With AAD (e.g., document ID, user ID, etc.)
let aad = AAD "user-123/document-456"B
let envelopeWithAAD =
    EncryptedEnvelope.encrypt encryptDEK (Some aad) plaintext
    |> AsyncResult.runSynchronously
    |> Result.orFail
Using Azure Key Vault for DEK Encryption
open Azure.Security.KeyVault.Keys.Cryptography

let encryptDEKWithVault (vaultClient: CryptographyClient) (DEK dek) = asyncResult {
    try
        let! result =
            vaultClient.EncryptAsync(EncryptionAlgorithm.RsaOaep256, dek)
            |> Async.AwaitTask
        return EncryptedData result.Ciphertext
    with ex ->
        return! Error $"Vault encryption failed: {ex.Message}"
}

let decryptDEKWithVault (vaultClient: CryptographyClient) (EncryptedData encryptedDek) = asyncResult {
    try
        let! result =
            vaultClient.DecryptAsync(EncryptionAlgorithm.RsaOaep256, encryptedDek)
            |> Async.AwaitTask
        return DEK result.Plaintext
    with ex ->
        return! Error $"Vault decryption failed: {ex.Message}"
}

Release

  1. Increment version in Cryptography.fsproj
  2. Update CHANGELOG.md
  3. Commit new version and tag it

Development

Requirements

Build

./build.sh build

Tests

./build.sh -t tests
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Feather.Cryptography:

Package Downloads
Alma.Authorization

Library for a Web App Authorization, login, token, securing requests, ...

Feather.Grpc

Library with low and high level helpers for gRPC.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.3.0 367 6/11/2026
2.2.0 259 6/9/2026
2.1.0 2,989 1/23/2026
2.0.0 129 1/14/2026
1.0.0 197 1/14/2026