- Overview
- Cryptography
- Database
- Java
- Python
- WebAPI
Developer activities
UiPath.Cryptography.Activities
Coded workflow API for symmetric encryption and decryption, keyed hashing, and PGP encryption, decryption, signing, clear-signing, verification, and key generation. Use these APIs when you design coded automations. Visit Coded Automations to learn about coded automations and how to design them using APIs.
- Service accessor:
cryptography(typeICryptographyService) - Required package:
"UiPath.Cryptography.Activities": "*"in theproject.jsondependencies.
Auto-imported namespaces
These namespaces are automatically available in coded workflows when this package is installed:
System
System.IO
System.Text
UiPath.Cryptography
UiPath.Cryptography.Activities
UiPath.Cryptography.Activities.API
UiPath.Cryptography.Enums
System
System.IO
System.Text
UiPath.Cryptography
UiPath.Cryptography.Activities
UiPath.Cryptography.Activities.API
UiPath.Cryptography.Enums
Service overview
The cryptography service exposes all operations as direct method calls. There is no connection, handle, or scope to open. It is registered as a stateless singleton, so the accessor is shared across the workflow and its methods are safe to call concurrently. Call methods on the service accessor directly:
var key = PasswordKey.FromPassword("mykey", Encoding.UTF8);
var ciphertext = cryptography.EncryptText("secret", EncryptionAlgorithm.AESGCM, SymmetricEncryptOptions.Classic(key));
var key = PasswordKey.FromPassword("mykey", Encoding.UTF8);
var ciphertext = cryptography.EncryptText("secret", EncryptionAlgorithm.AESGCM, SymmetricEncryptOptions.Classic(key));
Bytes, Text, and File forms
Every logical operation exposes three input/output forms. Pick the one that matches the data you already have:
| Form | Suffix | Input → Output | When to use |
|---|---|---|---|
| Bytes | (base) | byte[] → byte[] | Binary or already-loaded data. |
| Text | ...Text | string → string (Base64 or ASCII-armored) | Data arriving as text (HTTP, config, environment). |
| File | ...File | file path → file path | Data that lives on disk. |
Key material
Symmetric and keyed-hash operations take key material as one of two concrete CryptoKey subtypes. The class you pick determines which wire formats the key can be used with, and the type system enforces that at compile time through the format factories.
PasswordKey
Password material to be PBKDF2-stretched into a cipher key. Used with the Classic, Owasp2026, and OpenSslEnc wire formats.
| Factory | Purpose |
|---|---|
PasswordKey.FromPassword(string password, Encoding encoding) | Password or passphrase as a string. |
PasswordKey.FromPassword(SecureString password, Encoding encoding) | Same, sourced from a secret store or user input. |
PasswordKey stores the password internally as a SecureString (the string factory copies the input characters into one) and materializes the cipher-key bytes just-in-time on each operation. The bytes live only on the operation's stack frame and are never pinned to the PasswordKey instance; the intermediate buffers are zeroed after each materialization.
PasswordKey is IDisposable: calling Dispose() eagerly zeroes the protected buffer, and subsequent KeyBytes access throws ObjectDisposedException. Disposing is recommended for long-lived workflows.
RawKey
A literal cipher key of the algorithm's exact required length (for example, 32 bytes for AES-256). Used with the Raw wire format. No KDF is applied. RawKey is IDisposable: calling Dispose() zeroes the held key bytes in place.
| Factory | Purpose |
|---|---|
RawKey.FromBytes(byte[] keyBytes) | A key already loaded as bytes. |
RawKey.FromHex(string hex) | A key encoded as hex. |
RawKey.FromBase64(string base64) | A key encoded as Base64. |
The key length is not validated by the factories. It is checked when you call the encrypt or decrypt method, and an illegal length for the chosen algorithm throws ArgumentException listing the legal byte lengths (for example, 16, 24, or 32 for AES). Construct the key with exactly the algorithm's required key size.
Keyed-hash methods accept either subtype, because they take CryptoKey directly and have no wire-format axis.
Symmetric options
SymmetricEncryptOptions and SymmetricDecryptOptions bundle the key, the wire format, and any format-specific values (the IV for Raw, the KDF iterations for Owasp2026 and OpenSslEnc). Construct them through a format factory. The factory's key-parameter type enforces the key-kind and wire-format pairing at compile time, so a PasswordKey cannot be passed to Raw(...) and a RawKey cannot be passed to Classic(...).
| Factory | Format | Key type | Notes |
|---|---|---|---|
SymmetricEncryptOptions.Classic(PasswordKey key, Encoding encoding = null) | Classic | PasswordKey | Default. Frozen wire format for back-compatibility (PBKDF2-HMAC-SHA1 at 10,000 iterations). |
SymmetricEncryptOptions.Owasp2026(PasswordKey key, int kdfIterations = 1_300_000, Encoding encoding = null) | Owasp2026 | PasswordKey | Same layout as Classic, with PBKDF2-HMAC-SHA1 at OWASP's 2026 recommended iteration count. |
SymmetricEncryptOptions.Raw(RawKey key, byte[] iv = null, Encoding encoding = null) | Raw | RawKey | Caller-supplied key and IV, for third-party interoperability. |
SymmetricEncryptOptions.OpenSslEnc(PasswordKey key, int kdfIterations = 600_000, Encoding encoding = null, AesKeySize aesKeySize = AesKeySize.Aes256) | OpenSslEnc | PasswordKey | openssl enc-compatible (Salted__ magic with PBKDF2-HMAC-SHA256). aesKeySize selects AES-128, -192, or -256 to match the peer's openssl enc -aes-N-cbc. |
The SymmetricDecryptOptions factories take the same shape, except there is no IV on the decrypt side because the IV is read from the ciphertext stream automatically. The optional encoding: parameter sets the text encoding on the options (defaulting to UTF-8) and is consulted only by EncryptText and DecryptText.
A constructed options object is read-only but introspectable: CryptoOptions exposes the getters Key, Format, KdfIterations, and TextEncoding; SymmetricEncryptOptions additionally exposes IV and AesKeySize; and SymmetricDecryptOptions exposes AesKeySize.
IV and salt strategy
All symmetric encrypt methods are non-deterministic by default: a fresh random 8-byte salt (where applicable) and IV or nonce are generated on every call and embedded in the ciphertext stream. Encrypting the same plaintext twice always produces different ciphertext, and the matching decrypt method reconstructs the salt and IV from the same stream automatically.
- CBC-family algorithms (
AES,Rijndael,DES,TripleDES,RC2) use PKCS7 padding, CBC mode, and a random IV. AESGCMis Authenticated Encryption with Associated Data (AEAD), with a random 96-bit nonce and a 128-bit authentication tag. Recommended for new workflows.ChaCha20Poly1305is an AEAD alternative to AES-GCM.
For Raw, you can supply an explicit IV through SymmetricEncryptOptions.Raw(key, iv). Pass null (the factory default) to let the cipher generate one.
PGP key material
PGP methods take strongly-typed key handles. Construct them once and reuse them across calls.
| Factory | Purpose |
|---|---|
PgpPublicKey.FromBytes(byte[] keyBytes) | Public key from in-memory bytes (ASCII-armored or binary). |
PgpPublicKey.FromFilePath(string path) | Public key loaded from a .asc or .gpg file. |
PgpPrivateKey.FromBytes(byte[] keyBytes, string passphrase) | Private key and passphrase, bound together. |
PgpPrivateKey.FromBytes(byte[] keyBytes, SecureString passphrase) | Same, with a SecureString passphrase. |
PgpPrivateKey.FromFilePath(string path, string passphrase) | Private key from a file. |
PgpPrivateKey.FromFilePath(string path, SecureString passphrase) | Private key from a file, with a SecureString passphrase. |
Each key handle also exposes two instance methods:
| Member | Purpose |
|---|---|
byte[] ToBytes() | Returns a copy of the key bytes as loaded: ASCII-armored if the key was created from armored input, binary if loaded from binary. Keys returned by PgpGenerateKeys are ASCII-armored. |
void Save(string filePath, bool overwrite = false) | Writes the key to disk. Throws InvalidOperationException if the file exists and overwrite is false. |
PgpKeyPair (returned by PgpGenerateKeys, or constructed directly with new PgpKeyPair(publicKey, privateKey)) holds a matched public/private pair. Use pair.PublicKey and pair.PrivateKey, or deconstruct with var (pub, priv) = pair;. Persist with pair.PublicKey.Save(path) and pair.PrivateKey.Save(path) when you need files on disk.
Passing a PgpPrivateKey to an encrypt method implies signing, and passing a PgpPublicKey to a decrypt method implies signature verification. Separate bool sign or bool verifySignature flags are not used.
PgpPrivateKey stores its passphrase as a SecureString for the lifetime of the instance. It is materialized to a managed string only for the duration of each cryptographic operation, because the underlying BouncyCastle library requires a plain string. PgpPrivateKey is IDisposable: calling Dispose() eagerly zeroes the protected buffer. PgpPublicKey holds no secret material and is not IDisposable.
Relationship to the activities
The coded API and the Cryptography XAML activities run on the same cryptographic core, so they are at full parity on:
- Algorithms and keyed-hash algorithms
- Wire formats (
Classic,Owasp2026,Raw,OpenSslEnc) - IV, KDF iterations, AES key size, and encoding options
- Every PGP operation
Anything you can compute with an activity, you can compute with this service. The differences are about input/output shape and key-input form, not capability.
The coded API does more than the activities:
| Coded-only capability | Detail |
|---|---|
| Bytes input/output on every operation | EncryptBytes / DecryptBytes, KeyedHashBytes, PgpEncryptBytes / PgpDecryptBytes, PgpSignBytes / PgpClearSignBytes, PgpVerifyBytes / PgpVerifyClearSignedBytes. No activity has a byte[] form. |
Raw byte[] keys | RawKey.FromBytes(byte[]) for symmetric Raw and keyed hash. Activities can only supply raw keys as hex or Base64 strings. |
| In-memory PGP key material | PgpPublicKey.FromBytes and PgpPrivateKey.FromBytes let you operate without key files on disk. The activities require key files. |
| Text and Bytes sign / clearsign / verify | PgpSignText / PgpClearSignText, PgpVerifyText / PgpVerifyClearSignedText, and their Bytes forms. The activities expose only file-based sign, clearsign, and verify. |
In-memory PgpKeyPair | PgpGenerateKeys returns a usable key pair without forcing file output. |
The activities do two things the coded API does not, neither of which is a cryptographic capability:
- UiPath resource handles (
IResource/ILocalResource) as inputs and outputs. The coded API takes plainstringfile paths andbyte[]. - Continue On Error swallow-and-continue behavior. In a coded workflow you use ordinary
try/catchinstead, because every method throws on failure.
The Text activities split key encoding and plaintext encoding into two properties. In the coded API, the password encoding is set on PasswordKey.FromPassword(..., encoding) and the plaintext encoding through the options encoding: parameter. Both axes remain independently controllable.
Migrating from the prior coded API
The coded API surface introduced in the prior release has been consolidated in this version. The old call shapes (separate string / SecureString / byte[] key overloads with an Encoding parameter, plus a path-based PgpGenerateKeys) are replaced by a single options-based shape per operation, so the key-kind and wire-format pairing is enforced at compile time.
There are no [Obsolete] shims: code written against the prior API must be updated to compile against this package.
| Before | After |
|---|---|
EncryptBytes(input, algo, string key, Encoding enc) | EncryptBytes(input, algo, SymmetricEncryptOptions.Classic(PasswordKey.FromPassword(key, enc))) |
EncryptBytes(input, algo, SecureString key, Encoding enc) | EncryptBytes(input, algo, SymmetricEncryptOptions.Classic(PasswordKey.FromPassword(key, enc))) |
EncryptBytes(input, algo, byte[] keyBytes) | EncryptBytes(input, algo, SymmetricEncryptOptions.Raw(RawKey.FromBytes(keyBytes))) |
EncryptText(input, algo, key, enc) | EncryptText(input, algo, SymmetricEncryptOptions.Classic(PasswordKey.FromPassword(key, enc), enc)) |
EncryptFile(in, out, algo, key, enc, overwrite) | EncryptFile(in, out, algo, SymmetricEncryptOptions.Classic(PasswordKey.FromPassword(key, enc)), overwrite) |
DecryptBytes / DecryptText / DecryptFile | Same shape, with SymmetricDecryptOptions.<Format>(...). |
KeyedHashBytes(input, algo, string key, Encoding enc) | KeyedHashBytes(input, algo, PasswordKey.FromPassword(key, enc)) |
KeyedHashBytes(input, algo, byte[] keyBytes) | KeyedHashBytes(input, algo, RawKey.FromBytes(keyBytes)) |
KeyedHashText(input, algo, string key, Encoding enc) | KeyedHashText(input, algo, PasswordKey.FromPassword(key, enc), enc) |
KeyedHashFile(inputPath, algo, string key, Encoding enc) | KeyedHashFile(inputPath, algo, PasswordKey.FromPassword(key, enc)) |
PgpGenerateKeys(publicKeyPath, privateKeyPath, userId, passphrase, keySize) | var pair = PgpGenerateKeys(userId, passphrase, keySize); pair.PublicKey.Save(publicKeyPath); pair.PrivateKey.Save(privateKeyPath); |
Because every key and options type is new, code that references the old overloads fails to compile rather than silently picking up a different overload. The default text encoding remains UTF-8, so code that relied on the prior UTF-8 default needs no behavioral change beyond the options refactor.
Symmetric encryption
byte[] EncryptBytes(byte[] input, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options)
Encrypts arbitrary bytes. The options parameter carries the key and wire format. Returns the ciphertext per the chosen wire format.
string EncryptText(string input, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options)
Encrypts a string and returns the result as Base64-encoded ciphertext. The plaintext encoding is read from options.TextEncoding, defaulting to UTF-8.
void EncryptFile(string inputPath, string outputPath, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options, bool overwrite = false)
Reads a file, encrypts it, and writes the result. Throws InvalidOperationException if outputPath exists and overwrite is false.
Symmetric decryption
byte[] DecryptBytes(byte[] input, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options)
Decrypts ciphertext produced by EncryptBytes. options.Format must match the format used at encrypt time. Returns the plaintext bytes.
string DecryptText(string input, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options)
Decrypts a Base64-encoded ciphertext produced by EncryptText and returns the plaintext. The plaintext encoding is read from options.TextEncoding, must match the encoding used at encrypt time, and defaults to UTF-8.
void DecryptFile(string inputPath, string outputPath, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options, bool overwrite = false)
Reads an encrypted file and writes the plaintext. Throws InvalidOperationException if outputPath exists and overwrite is false.
Keyed hashing
Keyed-hash methods compute an HMAC (or a plain hash for non-HMAC algorithms) and return the result as an uppercase hex string. The operation is one-way and has no inverse.
string KeyedHashBytes(byte[] input, KeyedHashAlgorithms algorithm, CryptoKey key)
string KeyedHashText(string input, KeyedHashAlgorithms algorithm, CryptoKey key, Encoding encoding = null)
string KeyedHashFile(string inputPath, KeyedHashAlgorithms algorithm, CryptoKey key)
The optional encoding parameter on KeyedHashText controls how the input string is transcoded to bytes before hashing, and defaults to UTF-8. KeyedHashBytes operates on raw bytes, and KeyedHashFile hashes the file contents byte-for-byte, so neither has an encoding axis.
PGP encryption
If a signer is supplied, the encrypted payload is also signed with that private key.
byte[] PgpEncryptBytes(byte[] input, PgpPublicKey recipient, PgpPrivateKey signer = null)
string PgpEncryptText(string input, PgpPublicKey recipient, PgpPrivateKey signer = null)
void PgpEncryptFile(string inputPath, string outputPath, PgpPublicKey recipient, PgpPrivateKey signer = null, bool overwrite = false)
PGP decryption
If a verifier is supplied, the embedded signature is verified during decryption.
byte[] PgpDecryptBytes(byte[] input, PgpPrivateKey recipient, PgpPublicKey verifier = null)
string PgpDecryptText(string input, PgpPrivateKey recipient, PgpPublicKey verifier = null)
void PgpDecryptFile(string inputPath, string outputPath, PgpPrivateKey recipient, PgpPublicKey verifier = null, bool overwrite = false)
PGP signing (binary signature)
Produces a binary-signed payload. Verify it with the PgpVerify* methods.
byte[] PgpSignBytes(byte[] input, PgpPrivateKey signer)
string PgpSignText(string input, PgpPrivateKey signer)
void PgpSignFile(string inputPath, string outputPath, PgpPrivateKey signer, bool overwrite = false)
PGP clear-signing
Clear-signatures keep the original content human-readable with the signature appended. Verify them with the PgpVerifyClearSigned* methods.
byte[] PgpClearSignBytes(byte[] input, PgpPrivateKey signer)
string PgpClearSignText(string input, PgpPrivateKey signer)
void PgpClearSignFile(string inputPath, string outputPath, PgpPrivateKey signer, bool overwrite = false)
PGP verification
Binary signatures
Verify payloads produced by the PgpSign* methods (or by PgpEncrypt* with a signer).
| Method | Signature |
|---|---|
| Bytes | bool PgpVerifyBytes(byte[] input, PgpPublicKey verifier) |
| Text | bool PgpVerifyText(string input, PgpPublicKey verifier) |
| File | bool PgpVerifyFile(string inputPath, PgpPublicKey verifier) |
Returns true when the signature is valid, and false otherwise.
Clear-signatures
Verify payloads produced by the PgpClearSign* methods.
| Method | Signature |
|---|---|
| Bytes | bool PgpVerifyClearSignedBytes(byte[] input, PgpPublicKey verifier) |
| Text | bool PgpVerifyClearSignedText(string input, PgpPublicKey verifier) |
| File | bool PgpVerifyClearSignedFile(string inputPath, PgpPublicKey verifier) |
Public-key well-formedness
Confirms that a PgpPublicKey instance parses as a well-formed OpenPGP public key. This mirrors the PGP Verify activity's Validate Public Key verification type.
bool PgpVerifyPublicKey(PgpPublicKey key)
Returns true when the key is valid.
PGP key-pair generation
Generates an OpenPGP RSA key pair in memory and returns both halves as a matched PgpKeyPair. Persist by calling Save(path) on each half.
PgpKeyPair PgpGenerateKeys(string userId, string passphrase, RsaKeySize keySize = RsaKeySize.Rsa4096)
PgpKeyPair PgpGenerateKeys(string userId, SecureString passphrase, RsaKeySize keySize = RsaKeySize.Rsa4096)
Parameters:
userId(string) - The OpenPGP User ID; conventionally an RFC 2822 mailbox such asAlice Doe <alice@example.com>.passphrase- The passphrase that protects the generated private key. Bound to the returnedPgpPrivateKey.keySize(RsaKeySize) - The RSA key size. Defaults toRsa4096.Rsa3072andRsa2048are accepted for interoperability with legacy systems.
Returns a PgpKeyPair exposing pair.PublicKey and pair.PrivateKey.
Enum reference
EncryptionAlgorithm
Used by the symmetric encrypt and decrypt methods.
| Value | Notes |
|---|---|
AESGCM | AES-GCM with a 96-bit nonce and a 128-bit authentication tag. AEAD. Recommended for new workflows. |
ChaCha20Poly1305 | ChaCha20-Poly1305 AEAD. Non-FIPS. An alternative to AES-GCM. |
AES | AES in CBC mode. |
Rijndael | Rijndael in CBC mode. Obsolete and weak; avoid. |
DES | DES in CBC mode. Obsolete and weak; avoid. |
TripleDES | 3DES in CBC mode. Obsolete and weak; avoid. |
RC2 | RC2 in CBC mode. Obsolete and weak; avoid. |
PGP | Reserved. Use the dedicated PgpEncrypt* and PgpDecrypt* methods instead. |
SymmetricWireFormat
Used by SymmetricEncryptOptions.Format and SymmetricDecryptOptions.Format.
| Value | Notes |
|---|---|
Classic | UiPath's byte-stable layout, PBKDF2-HMAC-SHA1 at 10,000 iterations. Default. Frozen for back-compatibility. |
Owasp2026 | Classic layout with the OWASP-recommended iteration count (1,300,000). The caller can override it through kdfIterations. |
Raw | IV ‖ ciphertext [‖ tag]. The caller supplies the literal key (and optionally the IV). For third-party interoperability. |
OpenSslEnc | Salted__ ‖ salt(8) ‖ ciphertext [‖ tag], PBKDF2-HMAC-SHA256 at 600,000 iterations by default. Compatible with openssl enc -pbkdf2. |
KeyedHashAlgorithms
Used by the keyed-hash methods.
| Value | Type | Notes |
|---|---|---|
HMACSHA256 | Keyed HMAC | Recommended for MAC and integrity verification. |
HMACSHA384 | Keyed HMAC | |
HMACSHA512 | Keyed HMAC | |
SHA256 | Unkeyed hash | The key is ignored; equivalent to a plain SHA hash. |
SHA384 | Unkeyed hash | The key is ignored. |
SHA512 | Unkeyed hash | The key is ignored. |
HMACSHA1 | Keyed HMAC | Obsolete. SHA-1 is deprecated by NIST; prefer SHA256 or higher. |
HMACMD5 | Keyed HMAC | Obsolete. MD5 is broken; avoid for any security-sensitive use. |
SHA1 | Unkeyed hash | Obsolete. Collision attacks are demonstrated; do not use. |
RsaKeySize
Used by PgpGenerateKeys.
| Value | Bits |
|---|---|
Rsa2048 | 2048 |
Rsa3072 | 3072 |
Rsa4096 | 4096 (default) |
Common patterns
Encrypt and decrypt a string with AES-GCM (Classic, the default)
[Workflow]
public void Execute()
{
var key = PasswordKey.FromPassword("MySecretKey123!", Encoding.UTF8);
var ciphertext = cryptography.EncryptText("Sensitive data", EncryptionAlgorithm.AESGCM, SymmetricEncryptOptions.Classic(key));
Log($"Encrypted: {ciphertext}");
var plaintext = cryptography.DecryptText(ciphertext, EncryptionAlgorithm.AESGCM, SymmetricDecryptOptions.Classic(key));
Log($"Decrypted: {plaintext}");
}
[Workflow]
public void Execute()
{
var key = PasswordKey.FromPassword("MySecretKey123!", Encoding.UTF8);
var ciphertext = cryptography.EncryptText("Sensitive data", EncryptionAlgorithm.AESGCM, SymmetricEncryptOptions.Classic(key));
Log($"Encrypted: {ciphertext}");
var plaintext = cryptography.DecryptText(ciphertext, EncryptionAlgorithm.AESGCM, SymmetricDecryptOptions.Classic(key));
Log($"Decrypted: {plaintext}");
}
Encrypt with a caller-supplied raw key and IV (third-party interoperability)
[Workflow]
public void Execute()
{
// 32 bytes for AES-256
byte[] rawKeyBytes = Convert.FromBase64String("your-base64-encoded-32-byte-key==");
byte[] iv = Convert.FromHexString("a3f1b2c4d5e6f70819a0b1c2d3e4f506");
var key = RawKey.FromBytes(rawKeyBytes);
byte[] cipher = cryptography.EncryptBytes(
Encoding.UTF8.GetBytes("payload"),
EncryptionAlgorithm.AESGCM,
SymmetricEncryptOptions.Raw(key, iv));
// Decrypt. The IV is read from the ciphertext stream prefix, so there is no need to pass it again.
byte[] plain = cryptography.DecryptBytes(
cipher,
EncryptionAlgorithm.AESGCM,
SymmetricDecryptOptions.Raw(key));
}
[Workflow]
public void Execute()
{
// 32 bytes for AES-256
byte[] rawKeyBytes = Convert.FromBase64String("your-base64-encoded-32-byte-key==");
byte[] iv = Convert.FromHexString("a3f1b2c4d5e6f70819a0b1c2d3e4f506");
var key = RawKey.FromBytes(rawKeyBytes);
byte[] cipher = cryptography.EncryptBytes(
Encoding.UTF8.GetBytes("payload"),
EncryptionAlgorithm.AESGCM,
SymmetricEncryptOptions.Raw(key, iv));
// Decrypt. The IV is read from the ciphertext stream prefix, so there is no need to pass it again.
byte[] plain = cryptography.DecryptBytes(
cipher,
EncryptionAlgorithm.AESGCM,
SymmetricDecryptOptions.Raw(key));
}
Decrypt a file produced by openssl enc
[Workflow]
public void Execute()
{
// openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -md sha256 -salt -k password -in plain.txt -out cipher.bin
var key = PasswordKey.FromPassword("password", Encoding.UTF8);
cryptography.DecryptFile(
inputPath: @"C:\Documents\cipher.bin",
outputPath: @"C:\Documents\plain.txt",
algorithm: EncryptionAlgorithm.AES,
options: SymmetricDecryptOptions.OpenSslEnc(key),
overwrite: true);
}
[Workflow]
public void Execute()
{
// openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -md sha256 -salt -k password -in plain.txt -out cipher.bin
var key = PasswordKey.FromPassword("password", Encoding.UTF8);
cryptography.DecryptFile(
inputPath: @"C:\Documents\cipher.bin",
outputPath: @"C:\Documents\plain.txt",
algorithm: EncryptionAlgorithm.AES,
options: SymmetricDecryptOptions.OpenSslEnc(key),
overwrite: true);
}
Use a stronger KDF iteration count (Owasp2026)
[Workflow]
public void Execute()
{
var key = PasswordKey.FromPassword("MySecretKey", Encoding.UTF8);
// Owasp2026(key) defaults to kdfIterations = 1_300_000 (the OWASP 2026 recommendation).
var ciphertext = cryptography.EncryptBytes(
Encoding.UTF8.GetBytes("payload"),
EncryptionAlgorithm.AESGCM,
SymmetricEncryptOptions.Owasp2026(key));
// Decrypt must use the same iteration count. Owasp2026 does not store it in the wire format.
byte[] plain = cryptography.DecryptBytes(
ciphertext,
EncryptionAlgorithm.AESGCM,
SymmetricDecryptOptions.Owasp2026(key));
}
[Workflow]
public void Execute()
{
var key = PasswordKey.FromPassword("MySecretKey", Encoding.UTF8);
// Owasp2026(key) defaults to kdfIterations = 1_300_000 (the OWASP 2026 recommendation).
var ciphertext = cryptography.EncryptBytes(
Encoding.UTF8.GetBytes("payload"),
EncryptionAlgorithm.AESGCM,
SymmetricEncryptOptions.Owasp2026(key));
// Decrypt must use the same iteration count. Owasp2026 does not store it in the wire format.
byte[] plain = cryptography.DecryptBytes(
ciphertext,
EncryptionAlgorithm.AESGCM,
SymmetricDecryptOptions.Owasp2026(key));
}
Compute an HMAC-SHA256 for data integrity verification
[Workflow]
public void Execute()
{
byte[] hmacKey = Convert.FromBase64String("your-base64-hmac-key==");
var key = RawKey.FromBytes(hmacKey);
// Keyed-hash methods take a CryptoKey directly. There is no options object, because there is no wire-format axis.
var digest = cryptography.KeyedHashText("payload to verify", KeyedHashAlgorithms.HMACSHA256, key);
Log($"HMAC-SHA256: {digest}");
}
[Workflow]
public void Execute()
{
byte[] hmacKey = Convert.FromBase64String("your-base64-hmac-key==");
var key = RawKey.FromBytes(hmacKey);
// Keyed-hash methods take a CryptoKey directly. There is no options object, because there is no wire-format axis.
var digest = cryptography.KeyedHashText("payload to verify", KeyedHashAlgorithms.HMACSHA256, key);
Log($"HMAC-SHA256: {digest}");
}
PGP encrypt and sign, then decrypt and verify
[Workflow]
public void Execute()
{
var recipientPublic = PgpPublicKey.FromFilePath(@"C:\Keys\recipient_public.asc");
var senderPrivate = PgpPrivateKey.FromFilePath(@"C:\Keys\sender_private.asc", "senderPassphrase");
// Passing a signer to PgpEncrypt* implies sign-and-encrypt.
byte[] encrypted = cryptography.PgpEncryptBytes(
Encoding.UTF8.GetBytes("Signed and encrypted message"),
recipientPublic,
signer: senderPrivate);
var recipientPrivate = PgpPrivateKey.FromFilePath(@"C:\Keys\recipient_private.asc", "recipientPassphrase");
var senderPublic = PgpPublicKey.FromFilePath(@"C:\Keys\sender_public.asc");
// Passing a verifier to PgpDecrypt* implies verify-while-decrypting.
byte[] decrypted = cryptography.PgpDecryptBytes(
encrypted,
recipientPrivate,
verifier: senderPublic);
Log(Encoding.UTF8.GetString(decrypted));
}
[Workflow]
public void Execute()
{
var recipientPublic = PgpPublicKey.FromFilePath(@"C:\Keys\recipient_public.asc");
var senderPrivate = PgpPrivateKey.FromFilePath(@"C:\Keys\sender_private.asc", "senderPassphrase");
// Passing a signer to PgpEncrypt* implies sign-and-encrypt.
byte[] encrypted = cryptography.PgpEncryptBytes(
Encoding.UTF8.GetBytes("Signed and encrypted message"),
recipientPublic,
signer: senderPrivate);
var recipientPrivate = PgpPrivateKey.FromFilePath(@"C:\Keys\recipient_private.asc", "recipientPassphrase");
var senderPublic = PgpPublicKey.FromFilePath(@"C:\Keys\sender_public.asc");
// Passing a verifier to PgpDecrypt* implies verify-while-decrypting.
byte[] decrypted = cryptography.PgpDecryptBytes(
encrypted,
recipientPrivate,
verifier: senderPublic);
Log(Encoding.UTF8.GetString(decrypted));
}
Generate a new PGP key pair
[Workflow]
public void Execute()
{
PgpKeyPair pair = cryptography.PgpGenerateKeys(
userId: "Alice <alice@example.com>",
passphrase: "StrongPassphrase!",
keySize: RsaKeySize.Rsa4096);
pair.PublicKey.Save(@"C:\Keys\my_public.asc");
pair.PrivateKey.Save(@"C:\Keys\my_private.asc");
Log("Key pair generated.");
}
[Workflow]
public void Execute()
{
PgpKeyPair pair = cryptography.PgpGenerateKeys(
userId: "Alice <alice@example.com>",
passphrase: "StrongPassphrase!",
keySize: RsaKeySize.Rsa4096);
pair.PublicKey.Save(@"C:\Keys\my_public.asc");
pair.PrivateKey.Save(@"C:\Keys\my_private.asc");
Log("Key pair generated.");
}
Validate an inbound public key before storing it
[Workflow]
public void Execute()
{
// Armored public key arriving as text from an HTTP response or config.
string armoredPublicKey = LoadFromInbox();
var candidate = PgpPublicKey.FromBytes(Encoding.UTF8.GetBytes(armoredPublicKey));
if (!cryptography.PgpVerifyPublicKey(candidate))
{
throw new InvalidOperationException("Supplied content is not a valid OpenPGP public key.");
}
candidate.Save(@"C:\Keys\trusted_public.asc");
}
[Workflow]
public void Execute()
{
// Armored public key arriving as text from an HTTP response or config.
string armoredPublicKey = LoadFromInbox();
var candidate = PgpPublicKey.FromBytes(Encoding.UTF8.GetBytes(armoredPublicKey));
if (!cryptography.PgpVerifyPublicKey(candidate))
{
throw new InvalidOperationException("Supplied content is not a valid OpenPGP public key.");
}
candidate.Save(@"C:\Keys\trusted_public.asc");
}
- Auto-imported namespaces
- Service overview
- Bytes, Text, and File forms
- Key material
PasswordKeyRawKey- Symmetric options
- IV and salt strategy
- PGP key material
- Relationship to the activities
- Migrating from the prior coded API
- Symmetric encryption
byte[] EncryptBytes(byte[] input, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options)string EncryptText(string input, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options)void EncryptFile(string inputPath, string outputPath, EncryptionAlgorithm algorithm, SymmetricEncryptOptions options, bool overwrite = false)- Symmetric decryption
byte[] DecryptBytes(byte[] input, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options)string DecryptText(string input, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options)void DecryptFile(string inputPath, string outputPath, EncryptionAlgorithm algorithm, SymmetricDecryptOptions options, bool overwrite = false)- Keyed hashing
string KeyedHashBytes(byte[] input, KeyedHashAlgorithms algorithm, CryptoKey key)string KeyedHashText(string input, KeyedHashAlgorithms algorithm, CryptoKey key, Encoding encoding = null)string KeyedHashFile(string inputPath, KeyedHashAlgorithms algorithm, CryptoKey key)- PGP encryption
byte[] PgpEncryptBytes(byte[] input, PgpPublicKey recipient, PgpPrivateKey signer = null)string PgpEncryptText(string input, PgpPublicKey recipient, PgpPrivateKey signer = null)void PgpEncryptFile(string inputPath, string outputPath, PgpPublicKey recipient, PgpPrivateKey signer = null, bool overwrite = false)- PGP decryption
byte[] PgpDecryptBytes(byte[] input, PgpPrivateKey recipient, PgpPublicKey verifier = null)string PgpDecryptText(string input, PgpPrivateKey recipient, PgpPublicKey verifier = null)void PgpDecryptFile(string inputPath, string outputPath, PgpPrivateKey recipient, PgpPublicKey verifier = null, bool overwrite = false)- PGP signing (binary signature)
byte[] PgpSignBytes(byte[] input, PgpPrivateKey signer)string PgpSignText(string input, PgpPrivateKey signer)void PgpSignFile(string inputPath, string outputPath, PgpPrivateKey signer, bool overwrite = false)- PGP clear-signing
byte[] PgpClearSignBytes(byte[] input, PgpPrivateKey signer)string PgpClearSignText(string input, PgpPrivateKey signer)void PgpClearSignFile(string inputPath, string outputPath, PgpPrivateKey signer, bool overwrite = false)- PGP verification
- Binary signatures
- Clear-signatures
- Public-key well-formedness
- PGP key-pair generation
PgpKeyPair PgpGenerateKeys(string userId, string passphrase, RsaKeySize keySize = RsaKeySize.Rsa4096)PgpKeyPair PgpGenerateKeys(string userId, SecureString passphrase, RsaKeySize keySize = RsaKeySize.Rsa4096)- Enum reference
EncryptionAlgorithmSymmetricWireFormatKeyedHashAlgorithmsRsaKeySize- Common patterns
- Encrypt and decrypt a string with AES-GCM (Classic, the default)
- Encrypt with a caller-supplied raw key and IV (third-party interoperability)
- Decrypt a file produced by
openssl enc - Use a stronger KDF iteration count (
Owasp2026) - Compute an HMAC-SHA256 for data integrity verification
- PGP encrypt and sign, then decrypt and verify
- Generate a new PGP key pair
- Validate an inbound public key before storing it