SaQura Cryptography Library

Customer Documentation v1.0.4.2 January 2026

Introduction

SaQura is a professional cryptography library for .NET applications, providing enterprise-grade encryption capabilities including:

  • AES-256 - Symmetric encryption with authenticated encryption
  • RSA-4096 - Asymmetric encryption with automatic hybrid mode for large data
  • Quantum-Safe Encryption - Quantum-safe cryptography resistant to quantum computer attacks
  • Password Hashing - Secure password storage with 210,000 iterations

Namespace

All SaQura types are in the SaQura namespace:

using SaQura;

System Requirements

Supported Platforms

Platform Version Status
Windows10/11, Server 2016+Fully Supported
macOS10.15+ (Catalina)Fully Supported
LinuxUbuntu 18.04+, Debian 10+, RHEL 8+Fully Supported
iOS13.0+Fully Supported
AndroidAPI 21+ (Android 5.0)Fully Supported

Framework Requirements

  • .NET 8.0 or later
  • BouncyCastle.Cryptography 2.x (included as dependency)

Memory Requirements

  • Minimum: 50 MB RAM
  • Recommended: 128 MB RAM (for quantum key generation)

License Tiers & Features

Feature Comparison

Feature Free Basic Standard Pro Enterprise
RSA EncryptionWatermarkedFullFullFullFull
Password HashingWatermarkedFullFullFullFull
AES EncryptionLimitedLimitedFullFullFull
Quantum Encryption---FullFull
Output WatermarkYesNoNoNoNo
Priority Support----Yes

License Types

Standard License

  • Bound to a specific machine (Hardware ID)
  • Limited activations (typically 1-3 devices)
  • Registers with server in background (non-blocking)
  • Ideal for desktop applications and developer machines

Distribution License

  • Not bound to hardware
  • Unlimited activations
  • Does NOT contact the server (fully offline)
  • Ideal for distributed applications and libraries
  • Perfect for embedding in App Store / Play Store apps

Installation

Step 1: Add NuGet Package

Add the SaQura NuGet package to your project:

dotnet add package SaQura

Or via Package Manager Console in Visual Studio:

Install-Package SaQura

Step 2: Add License File to Project

After purchasing, you receive two license files:

  • YourProduct_standard.lic - For standard installations
  • YourProduct_distribution.lic - For distribution in your software

For Desktop/Server Applications

  1. Copy your .lic file to your project
  2. Set "Copy to Output Directory" to "Copy if newer"
<ItemGroup>
  <None Update="license.lic">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

For Distributed Applications (Embedded License)

  1. Add the .lic file as an embedded resource
  2. Set "Build Action" to "Embedded Resource"
<ItemGroup>
  <EmbeddedResource Include="license.lic" />
</ItemGroup>

License Activation

After purchasing, you receive:

  • A License Key (e.g., PRO-VRY1-ELG4-YOPM-FFOR)
  • Two License Files:
    • YourProduct_standard.lic - For your development machine
    • YourProduct_distribution.lic - For your published app

Option A: License Key (Online Activation)

When to use: You have a license key like PRO-XXXX-XXXX-XXXX-XXXX

Requirements: Internet connection

using SaQura;

var result = await License.ActivateLicenseAsync("PRO-VRY1-ELG4-YOPM-FFOR");

if (result.Success)
{
    Console.WriteLine("License activated!");
}

The license is automatically saved and persists across app restarts.

Option B: Standard License File (Developer Machine)

When to use: You have a _standard.lic file for your development computer

Limitations: Hardware-bound, max 3 devices

using SaQura;

var result = await License.ActivateLicenseFileAsync("/path/to/MyProduct_standard.lic");

if (result.Success)
{
    Console.WriteLine("License activated!");
}

Option C: Distribution License (App Store / Play Store)

When to use: You have a _distribution.lic file for your published app

Benefits: No hardware binding, works on unlimited customer devices, no internet required

Step 1: Add the license file to your project

MyProject/
└── Resources/
    └── Raw/
        └── license.lic   ← Copy your _distribution.lic file here

Step 2: Load and activate at app startup

For MAUI / Mobile Apps (Complete Example):

// MauiProgram.cs
using Microsoft.Extensions.Logging;
using SaQura;

namespace MyApp;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        // Register your services and ViewModels here...

        var app = builder.Build();

        // Activate license at startup (runs in background)
        Task.Run(async () => await ActivateLicenseAsync());

        return app;
    }

    private static async Task ActivateLicenseAsync()
    {
        try
        {
            // Already licensed from previous session?
            if (ApiLicense.IsLicensed)
            {
                System.Diagnostics.Debug.WriteLine($"[SaQura] License active: {ApiLicense.CurrentTier}");
                return;
            }

            // Load license from Resources/Raw/license.lic
            using var stream = await FileSystem.OpenAppPackageFileAsync("license.lic");
            using var reader = new StreamReader(stream);
            var licenseJson = await reader.ReadToEndAsync();

            // Activate
            var result = await ApiLicense.ActivateLicenseFromJsonAsync(licenseJson);

            if (result.Success)
            {
                System.Diagnostics.Debug.WriteLine($"[SaQura] License activated: {ApiLicense.CurrentTier}");
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"[SaQura] Activation failed: {result.ErrorMessage}");
            }
        }
        catch (FileNotFoundException)
        {
            System.Diagnostics.Debug.WriteLine("[SaQura] No license file - running in Free mode");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"[SaQura] Error: {ex.Message}");
        }
    }
}

For Desktop / Console Apps:

using SaQura;

var licenseContent = File.ReadAllText("license.lic");
var result = await License.ActivateLicenseFromJsonAsync(licenseContent);

if (result.Success)
{
    Console.WriteLine("License activated!");
}

Checking License Status

// Check if licensed
if (ApiLicense.IsLicensed)
{
    Console.WriteLine($"Tier: {ApiLicense.CurrentTier}");
    Console.WriteLine($"Days remaining: {ApiLicense.GetDaysRemaining()}");

    // Check specific features
    Console.WriteLine($"AES Available: {ApiLicense.IsAESAvailable}");
    Console.WriteLine($"RSA Available: {ApiLicense.IsRSAAvailable}");
    Console.WriteLine($"Quantum Available: {ApiLicense.IsQuantumAvailable}");
}

// Get detailed status
Console.WriteLine(ApiLicense.GetLicenseStatus());

Application Startup Pattern

public class Program
{
    public static async Task Main(string[] args)
    {
        // Activate license at startup
        await InitializeLicenseAsync();

        // Your application code
        await RunApplicationAsync();
    }

    private static async Task InitializeLicenseAsync()
    {
        // Try to activate from file
        var result = await ApiLicense.ActivateLicenseFileAsync("license.lic");

        if (!result.Success)
        {
            Console.WriteLine("Warning: Running in unlicensed mode");
            Console.WriteLine("Some features will be limited or watermarked");
        }
        else if (ApiLicense.NeedsRenewal())
        {
            Console.WriteLine("Warning: License expires soon. Please renew.");
        }
    }
}

API Reference

Licensing API (ApiLicense)

Method Description
ActivateLicenseAsync(string key)Activate using license key
ActivateLicenseFileAsync(string path)Activate from .lic file
ActivateLicenseFromJsonAsync(string json)Activate from JSON content
ValidateLicenseAsync(bool forceOnline)Validate current license
DeactivateLicenseAsync()Deactivate current license
GetLicenseStatus()Get human-readable status
GetHardwareId()Get machine's hardware ID

Properties

Property Description
IsLicensedWhether a valid license is active
CurrentTierCurrent license tier (Free, Basic, Standard, Pro, Enterprise)
IsAESAvailableWhether AES features are enabled
IsRSAAvailableWhether RSA features are enabled
IsQuantumAvailableWhether Quantum features are enabled
IsPasswordHashingAvailableWhether password hashing is enabled
RequiresWatermarkWhether output will be watermarked

Events

Event Description
OnLicenseRejectedFired when server rejects activation (max activations reached)

Handling License Rejection

For Standard licenses, the server validates activations in the background. If rejected (e.g., max activations reached), the license is automatically deactivated and an event is fired:

// Subscribe to rejection events at startup
ApiLicense.OnLicenseRejected += (errorMessage) =>
{
    // Show error to user
    Console.WriteLine($"License rejected: {errorMessage}");

    // Prompt for new license or contact support
    ShowLicenseErrorDialog(errorMessage);
};

// Activate license - returns immediately
var result = await ApiLicense.ActivateLicenseFileAsync("license.lic");
// Server validation happens in background (non-blocking)

Note: Distribution licenses never contact the server and cannot be rejected.

AES Encryption (AES)

Method Description
GenerateAESKey()Generate a new AES-256 key
GenerateKeyPairAsync()Generate key and nonce
EncryptAsync(string plainText, string key)Encrypt text
DecryptAsync(string cipherText, string key)Decrypt text
GenerateSalt()Generate salt for key derivation
DeriveKeyFromPassword(string password, string salt)Derive key from password

RSA Encryption (RSAKey)

Method Description
NewKeyPairAsync()Generate RSA-4096 key pair (byte arrays)
NewKeyPairAsStringAsync()Generate RSA-4096 key pair (strings)
EncryptAsync(byte[] data, byte[] publicKey)Encrypt data
DecryptAsync(byte[] encryptedData, byte[] privateKey)Decrypt data
SignAsync(byte[] data, byte[] privateKey)Sign data
VerifyAsync(byte[] data, byte[] signature, byte[] publicKey)Verify signature

Quantum Encryption (Quantum)

Method Description
GenerateKeyPair(QuantumStrength, QuantumGeneration)Generate quantum key pair
GenerateKeyPairAsync(QuantumStrength, QuantumGeneration)Generate key pair (async)
GetRecommendedGeneration(bool isMobile, bool requiresHighSecurity)Get recommended generation
GetSecurityAssessment(QuantumGeneration)Get security info for generation

Quantum Generations

Generation Description Use Case
Gen2Mobile-friendlyMobile apps, moderate security
Gen4AES authenticatedGeneral purpose, recommended
Gen5HardenedHigh security environments
Gen6Mobile-optimized.NET MAUI, mobile platforms
Gen7Hybrid RSA+QuantumCritical infrastructure (Pro+)

Quantum Strength Levels

Level Description
StandardStandard security level (recommended)
MediumAlternative configuration
HighestMaximum security

Password Hashing (PasswordHasher)

Method Description
HashPasswordAsync(string password)Hash a password
VerifyPasswordAsync(string password, string hash)Verify password against hash
VerifyAndMigrateAsync(string password, string hash)Verify and upgrade hash if needed

Code Examples

AES Encryption

using SaQura;

// Generate a key
var key = AES.GenerateAESKey();

// Encrypt
var plainText = "Secret message";
var encrypted = await AES.EncryptAsync(plainText, key);

// Decrypt
var decrypted = await AES.DecryptAsync(encrypted, key);

Console.WriteLine($"Original: {plainText}");
Console.WriteLine($"Decrypted: {decrypted}");

Password-Based Encryption

using SaQura;

// User's password
var password = "user_password_123";

// Generate salt (store this with the encrypted data)
var salt = AES.GenerateSalt();

// Derive key from password
var key = AES.DeriveKeyFromPassword(password, salt);

// Encrypt
var encrypted = await AES.EncryptAsync("Sensitive data", key);

// To decrypt later, use the same password and salt
var decryptionKey = AES.DeriveKeyFromPassword(password, salt);
var decrypted = await AES.DecryptAsync(encrypted, decryptionKey);

RSA Encryption

using SaQura;
using System.Text;

// Generate key pair
var (privateKey, publicKey) = await RSAKey.NewKeyPairAsStringAsync();

// Encrypt with public key
var plainText = "Secret message";
var plainBytes = Encoding.UTF8.GetBytes(plainText);
var publicKeyBytes = Encoding.UTF8.GetBytes(publicKey);

var encrypted = await RSAKey.EncryptAsync(plainBytes, publicKeyBytes);

// Decrypt with private key
var privateKeyBytes = Encoding.UTF8.GetBytes(privateKey);
var decryptedBytes = await RSAKey.DecryptAsync(encrypted, privateKeyBytes);
var decrypted = Encoding.UTF8.GetString(decryptedBytes);

Console.WriteLine($"Decrypted: {decrypted}");

Digital Signatures

using SaQura;
using System.Text;

// Generate key pair
var (privateKey, publicKey) = await RSAKey.NewKeyPairAsync();

// Sign data
var data = Encoding.UTF8.GetBytes("Document to sign");
var signature = await RSAKey.SignAsync(data, privateKey);

// Verify signature
var isValid = await RSAKey.VerifyAsync(data, signature, publicKey);
Console.WriteLine($"Signature valid: {isValid}");

Quantum-Safe Encryption (Pro+)

using SaQura;

// Get recommended generation for your platform
var generation = Quantum.GetRecommendedGeneration(
    isMobile: false,
    requiresHighestSecurity: false);

// Generate quantum key pair
var (publicKey, privateKey) = Quantum.GenerateKeyPair(
    QuantumStrength.Standard,
    generation);

Console.WriteLine($"Public key size: {publicKey.Length} bytes");
Console.WriteLine($"Generation: {generation}");
Console.WriteLine($"Assessment: {Quantum.GetSecurityAssessment(generation)}");

Password Hashing

using SaQura;

// Hash a password
var password = "MySecurePassword123!";
var hash = await PasswordHasher.HashPasswordAsync(password);

// Store 'hash' in your database

// Verify password during login
var isValid = await PasswordHasher.VerifyPasswordAsync(password, hash);

if (isValid)
{
    Console.WriteLine("Login successful!");
}
else
{
    Console.WriteLine("Invalid password!");
}

Complete Application Example

using SaQura;
using System.Text;

public class SecureDataService
{
    private readonly string _aesKey;

    public SecureDataService()
    {
        // Initialize license at application start
        InitializeLicense();

        // Generate or load encryption key
        _aesKey = AES.GenerateAESKey();
    }

    private void InitializeLicense()
    {
        var result = ApiLicense.ActivateLicenseFile("license.lic");

        if (result.Success)
        {
            Console.WriteLine($"Licensed: {ApiLicense.CurrentTier}");
        }
        else
        {
            Console.WriteLine("Warning: Unlicensed mode");
        }
    }

    public async Task<string> EncryptDataAsync(string data)
    {
        // Check if AES is available
        if (!ApiLicense.IsAESAvailable)
        {
            throw new InvalidOperationException(
                "AES encryption requires a Standard license or higher.");
        }

        return await AES.EncryptAsync(data, _aesKey);
    }

    public async Task<string> DecryptDataAsync(string encryptedData)
    {
        return await AES.DecryptAsync(encryptedData, _aesKey);
    }

    public async Task<string> HashPasswordAsync(string password)
    {
        return await PasswordHasher.HashPasswordAsync(password);
    }

    public async Task<bool> VerifyPasswordAsync(string password, string hash)
    {
        return await PasswordHasher.VerifyPasswordAsync(password, hash);
    }
}

Best Practices

License Management

  1. Activate Early - Activate the license at application startup
  2. Handle Failures Gracefully - Always check result.Success
  3. Monitor Expiration - Use NeedsRenewal() to warn users
  4. Secure License Files - Don't commit license files to public repositories

Key Management

  1. Never Hardcode Keys - Generate keys at runtime or load from secure storage
  2. Rotate Keys Regularly - Especially for long-running applications
  3. Secure Key Storage - Use platform-specific secure storage (Keychain, DPAPI, etc.)
  4. Clear Sensitive Data - Use SecureClear() extension on byte arrays
// Example: Clear sensitive data
var key = AES.GenerateAESKey();
// ... use the key ...
// When done, clear it
Encoding.UTF8.GetBytes(key).SecureClear();

Error Handling

try
{
    var encrypted = await AES.EncryptAsync(plainText, key);
}
catch (LicenseException ex)
{
    // Feature not available in current tier
    Console.WriteLine($"License error: {ex.Message}");
    Console.WriteLine($"Required feature: {ex.Feature}");
}
catch (CryptographicException ex)
{
    // Encryption/decryption error
    Console.WriteLine($"Crypto error: {ex.Message}");
}

Performance Tips

  1. Reuse Keys - Don't regenerate keys for each operation
  2. Use Async Methods - All crypto methods have async variants
  3. Batch Operations - Encrypt multiple items with the same key
  4. Quantum Key Pre-generation - Generate quantum keys in advance (resource-intensive)

Troubleshooting

Common Issues

"License validation failed"

Cause: The license file is corrupt or has been modified.

Solution:

  1. Re-download the license file from your account
  2. Ensure the file was not modified in transit
  3. Contact support if the issue persists

"Hardware ID mismatch"

Cause: Standard license is bound to a different machine.

Solution:

  1. Deactivate on the old machine
  2. Activate on the new machine
  3. If you've reached activation limit, contact support

"License rejected by server" / "Max activations reached"

Cause: Standard license has reached maximum device activations.

Solution:

  1. Deactivate the license on unused machines
  2. Contact support to reset activations
  3. Consider upgrading to Enterprise for more activations
  4. Use Distribution license for unlimited device deployment

Note: This error appears via the OnLicenseRejected event. Subscribe to this event to handle the rejection gracefully in your UI.

"Feature requires [Tier] license"

Cause: Attempting to use a feature not included in your tier.

Solution:

  1. Check the feature matrix in the License Tiers section
  2. Upgrade your license tier at kyototech.jp/pricing

"Output is watermarked"

Cause: Running in Free mode or with an expired license.

Solution:

  1. Verify license is activated: ApiLicense.IsLicensed
  2. Check license status: ApiLicense.GetLicenseStatus()
  3. Renew if expired

Quantum key generation is slow

Cause: Quantum key generation is computationally intensive.

Solution:

  1. Pre-generate keys during application idle time
  2. Use Gen6 for mobile platforms (optimized)
  3. Cache key pairs for reuse

Getting Hardware ID

If support requests your hardware ID:

var hardwareId = ApiLicense.GetHardwareId();
Console.WriteLine($"Hardware ID: {hardwareId}");

Support & Contact

Resources

Support Levels

Tier Support Level Response Time
FreeCommunityBest effort
BasicEmail72 hours
StandardEmail48 hours
ProEmail + Chat24 hours
EnterprisePriority + Phone4 hours

Reporting Issues

When contacting support, please include:

  1. Your license key (first 8 characters only)
  2. Hardware ID: ApiLicense.GetHardwareId()
  3. Library version
  4. Error messages (full stack trace)
  5. Platform (OS, .NET version)

Legal Disclaimer

SaQura is provided "AS IS" without warranty. KyotoTech LLC is not liable for data loss, security breaches, or damages arising from use of this library. You are responsible for key management and security audits. For full terms, see Terms of Service.

Copyright 2025 KyotoTech LLC. All Rights Reserved.
This documentation is for SaQura version 1.0.4.2.