GPAL's Cryptography class wraps common .NET crypto operations - AES encryption in multiple modes, hashing, RSA signing and verification, and PBKDF2 key derivation - behind one fluent, chainable object. This tutorial walks through generating keys, encrypting and decrypting data, chaining encryption into hashing, and signing/verifying with RSA.
This is a trimmed version of the actual test program. It generates an RSA key pair and an AES key/IV, encrypts and decrypts a message, chains encryption straight into hashing, and signs/verifies the original data with RSA.
using System;
using System.Text;
using GenerallyPositive;
using static GenerallyPositive.Enums;
byte[] data = Encoding.UTF8.GetBytes("Hello, GPAL Cryptography!");
var (rsaPrivateKey, rsaPublicKey) = Cryptography.GenerateRsaKeyPair();
var crypto = new Cryptography();
GPAL.WithPublishToConsole();
// Generate a key and IV, then encrypt with AES/GCM
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithMode(CryptoMode.GCM)
.GenerateIV(out byte[] iv)
.GenerateKey(out byte[] key)
.WithInputData(data)
.Encrypt(out byte[] encrypted);
// Decrypt using the same key and IV, switching to CBC/PKCS7
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithMode(CryptoMode.CBC)
.WithPadding(CryptoPadding.PKCS7)
.WithKey(key)
.WithIV(iv)
.WithInputData(encrypted)
.Decrypt(out string decrypted);
Console.WriteLine($"Decrypted value: [{decrypted}]");
// Encrypt, then immediately hash the same input data
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithKey(key)
.WithIV(iv)
.WithInputData(data)
.Encrypt(out encrypted)
.WithAlgorithm(CryptoAlgorithm.SHA256)
.Hash(out byte[] hash);
// Sign with the RSA private key, verify with the public key
crypto.WithAlgorithm(CryptoAlgorithm.SHA256withRSA)
.WithKey(rsaPrivateKey)
.WithInputData(data)
.Sign(out byte[] signature)
.WithKey(rsaPublicKey)
.WithSignature(signature)
.Verify(out bool isValid);
Console.WriteLine($"Verification result: [{isValid}]");
Cryptography.GenerateRsaKeyPair() is a static helper that returns a private and public key in one call. For symmetric work, GenerateIV and GenerateKey are instance methods on a Cryptography object - calling them stores the generated values internally (_iv and _key) so later calls like Encrypt can reuse them without you passing anything explicitly.
var (rsaPrivateKey, rsaPublicKey) = Cryptography.GenerateRsaKeyPair();
var crypto = new Cryptography();
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithMode(CryptoMode.GCM)
.GenerateIV(out byte[] iv)
.GenerateKey(out byte[] key)
.WithInputData(data)
.Encrypt(out byte[] encrypted);
GenerateIV and GenerateKey both hand the value back to you via out parameters AND store it internally for the next call in the chain. That's why Encrypt doesn't need a separate WithKey/WithIV call here - it reuses what was just generated.
WithAlgorithm and WithMode (and WithPadding for block modes that need it) configure how the next operation runs. Here decryption explicitly sets WithKey and WithIV to the values generated during encryption, switches to CBC with PKCS7 padding, and calls Decrypt with an out string to get the plaintext back directly.
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithMode(CryptoMode.CBC)
.WithPadding(CryptoPadding.PKCS7)
.WithKey(key)
.WithIV(iv)
.WithInputData(encrypted)
.Decrypt(out string decrypted);
Because Encrypt returns the same crypto object, you can immediately switch algorithm to SHA256 and call Hash - it reuses _inputData (the original plaintext, not the just-produced ciphertext) for the hash. This is a convenient way to produce both an encrypted payload and an integrity hash of the source data in one chain.
crypto.WithAlgorithm(CryptoAlgorithm.AES)
.WithKey(key)
.WithIV(iv)
.WithInputData(data)
.Encrypt(out encrypted)
.WithAlgorithm(CryptoAlgorithm.SHA256)
.Hash(out byte[] hash);
Switching WithAlgorithm to SHA256 after Encrypt does not hash the ciphertext - it hashes whatever _inputData currently holds, which here is still the original plaintext set by the earlier WithInputData(data) call.
SHA256withRSA covers both signing and verification. Sign takes the RSA private key and the data, producing a signature. Verify then takes the public key plus that signature and reports whether it matches - the standard pattern for proving data hasn't been tampered with.
crypto.WithAlgorithm(CryptoAlgorithm.SHA256withRSA)
.WithKey(rsaPrivateKey)
.WithInputData(data)
.Sign(out byte[] signature)
.WithKey(rsaPublicKey)
.WithSignature(signature)
.Verify(out bool isValid);
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();