UiPath Documentation
activities
latest
false

Developer activities

Cryptography coded automation APIs

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 (type ICryptographyService)
  • Required package: "UiPath.Cryptography.Activities": "*" in the project.json dependencies.

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:

FormSuffixInput → OutputWhen to use
Bytes(base)byte[]byte[]Binary or already-loaded data.
Text...Textstringstring (Base64 or ASCII-armored)Data arriving as text (HTTP, config, environment).
File...Filefile path → file pathData 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.

FactoryPurpose
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.

FactoryPurpose
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(...).

FactoryFormatKey typeNotes
SymmetricEncryptOptions.Classic(PasswordKey key, Encoding encoding = null)ClassicPasswordKeyDefault. 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)Owasp2026PasswordKeySame layout as Classic, with PBKDF2-HMAC-SHA1 at OWASP's 2026 recommended iteration count.
SymmetricEncryptOptions.Raw(RawKey key, byte[] iv = null, Encoding encoding = null)RawRawKeyCaller-supplied key and IV, for third-party interoperability.
SymmetricEncryptOptions.OpenSslEnc(PasswordKey key, int kdfIterations = 600_000, Encoding encoding = null, AesKeySize aesKeySize = AesKeySize.Aes256)OpenSslEncPasswordKeyopenssl 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.
  • AESGCM is Authenticated Encryption with Associated Data (AEAD), with a random 96-bit nonce and a 128-bit authentication tag. Recommended for new workflows.
  • ChaCha20Poly1305 is 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.

FactoryPurpose
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:

MemberPurpose
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 capabilityDetail
Bytes input/output on every operationEncryptBytes / DecryptBytes, KeyedHashBytes, PgpEncryptBytes / PgpDecryptBytes, PgpSignBytes / PgpClearSignBytes, PgpVerifyBytes / PgpVerifyClearSignedBytes. No activity has a byte[] form.
Raw byte[] keysRawKey.FromBytes(byte[]) for symmetric Raw and keyed hash. Activities can only supply raw keys as hex or Base64 strings.
In-memory PGP key materialPgpPublicKey.FromBytes and PgpPrivateKey.FromBytes let you operate without key files on disk. The activities require key files.
Text and Bytes sign / clearsign / verifyPgpSignText / PgpClearSignText, PgpVerifyText / PgpVerifyClearSignedText, and their Bytes forms. The activities expose only file-based sign, clearsign, and verify.
In-memory PgpKeyPairPgpGenerateKeys 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 plain string file paths and byte[].
  • Continue On Error swallow-and-continue behavior. In a coded workflow you use ordinary try/catch instead, because every method throws on failure.
Note:

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.

BeforeAfter
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 / DecryptFileSame 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).

MethodSignature
Bytesbool PgpVerifyBytes(byte[] input, PgpPublicKey verifier)
Textbool PgpVerifyText(string input, PgpPublicKey verifier)
Filebool PgpVerifyFile(string inputPath, PgpPublicKey verifier)

Returns true when the signature is valid, and false otherwise.

Clear-signatures

Verify payloads produced by the PgpClearSign* methods.

MethodSignature
Bytesbool PgpVerifyClearSignedBytes(byte[] input, PgpPublicKey verifier)
Textbool PgpVerifyClearSignedText(string input, PgpPublicKey verifier)
Filebool 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 as Alice Doe <[email protected]>.
  • passphrase - The passphrase that protects the generated private key. Bound to the returned PgpPrivateKey.
  • keySize (RsaKeySize) - The RSA key size. Defaults to Rsa4096. Rsa3072 and Rsa2048 are 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.

ValueNotes
AESGCMAES-GCM with a 96-bit nonce and a 128-bit authentication tag. AEAD. Recommended for new workflows.
ChaCha20Poly1305ChaCha20-Poly1305 AEAD. Non-FIPS. An alternative to AES-GCM.
AESAES in CBC mode.
RijndaelRijndael in CBC mode. Obsolete and weak; avoid.
DESDES in CBC mode. Obsolete and weak; avoid.
TripleDES3DES in CBC mode. Obsolete and weak; avoid.
RC2RC2 in CBC mode. Obsolete and weak; avoid.
PGPReserved. Use the dedicated PgpEncrypt* and PgpDecrypt* methods instead.

SymmetricWireFormat

Used by SymmetricEncryptOptions.Format and SymmetricDecryptOptions.Format.

ValueNotes
ClassicUiPath's byte-stable layout, PBKDF2-HMAC-SHA1 at 10,000 iterations. Default. Frozen for back-compatibility.
Owasp2026Classic layout with the OWASP-recommended iteration count (1,300,000). The caller can override it through kdfIterations.
RawIV ‖ ciphertext [‖ tag]. The caller supplies the literal key (and optionally the IV). For third-party interoperability.
OpenSslEncSalted__ ‖ 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.

ValueTypeNotes
HMACSHA256Keyed HMACRecommended for MAC and integrity verification.
HMACSHA384Keyed HMAC
HMACSHA512Keyed HMAC
SHA256Unkeyed hashThe key is ignored; equivalent to a plain SHA hash.
SHA384Unkeyed hashThe key is ignored.
SHA512Unkeyed hashThe key is ignored.
HMACSHA1Keyed HMACObsolete. SHA-1 is deprecated by NIST; prefer SHA256 or higher.
HMACMD5Keyed HMACObsolete. MD5 is broken; avoid for any security-sensitive use.
SHA1Unkeyed hashObsolete. Collision attacks are demonstrated; do not use.

RsaKeySize

Used by PgpGenerateKeys.

ValueBits
Rsa20482048
Rsa30723072
Rsa40964096 (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 <[email protected]>",
        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 <[email protected]>",
        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");
}

Was this page helpful?

Connect

Need help? Support

Want to learn? UiPath Academy

Have questions? UiPath Forum

Stay updated