SaQura Cryptography Library
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 |
|---|---|---|
| Windows | 10/11, Server 2016+ | Fully Supported |
| macOS | 10.15+ (Catalina) | Fully Supported |
| Linux | Ubuntu 18.04+, Debian 10+, RHEL 8+ | Fully Supported |
| iOS | 13.0+ | Fully Supported |
| Android | API 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 Encryption | Watermarked | Full | Full | Full | Full |
| Password Hashing | Watermarked | Full | Full | Full | Full |
| AES Encryption | Limited | Limited | Full | Full | Full |
| Quantum Encryption | - | - | - | Full | Full |
| Output Watermark | Yes | No | No | No | No |
| 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 installationsYourProduct_distribution.lic- For distribution in your software
For Desktop/Server Applications
- Copy your
.licfile to your project - Set "Copy to Output Directory" to "Copy if newer"
<ItemGroup>
<None Update="license.lic">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
For Distributed Applications (Embedded License)
- Add the
.licfile as an embedded resource - 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 machineYourProduct_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 |
|---|---|
IsLicensed | Whether a valid license is active |
CurrentTier | Current license tier (Free, Basic, Standard, Pro, Enterprise) |
IsAESAvailable | Whether AES features are enabled |
IsRSAAvailable | Whether RSA features are enabled |
IsQuantumAvailable | Whether Quantum features are enabled |
IsPasswordHashingAvailable | Whether password hashing is enabled |
RequiresWatermark | Whether output will be watermarked |
Events
| Event | Description |
|---|---|
OnLicenseRejected | Fired 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 |
|---|---|---|
| Gen2 | Mobile-friendly | Mobile apps, moderate security |
| Gen4 | AES authenticated | General purpose, recommended |
| Gen5 | Hardened | High security environments |
| Gen6 | Mobile-optimized | .NET MAUI, mobile platforms |
| Gen7 | Hybrid RSA+Quantum | Critical infrastructure (Pro+) |
Quantum Strength Levels
| Level | Description |
|---|---|
| Standard | Standard security level (recommended) |
| Medium | Alternative configuration |
| Highest | Maximum 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
- Activate Early - Activate the license at application startup
- Handle Failures Gracefully - Always check
result.Success - Monitor Expiration - Use
NeedsRenewal()to warn users - Secure License Files - Don't commit license files to public repositories
Key Management
- Never Hardcode Keys - Generate keys at runtime or load from secure storage
- Rotate Keys Regularly - Especially for long-running applications
- Secure Key Storage - Use platform-specific secure storage (Keychain, DPAPI, etc.)
- 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
- Reuse Keys - Don't regenerate keys for each operation
- Use Async Methods - All crypto methods have async variants
- Batch Operations - Encrypt multiple items with the same key
- 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:
- Re-download the license file from your account
- Ensure the file was not modified in transit
- Contact support if the issue persists
"Hardware ID mismatch"
Cause: Standard license is bound to a different machine.
Solution:
- Deactivate on the old machine
- Activate on the new machine
- If you've reached activation limit, contact support
"License rejected by server" / "Max activations reached"
Cause: Standard license has reached maximum device activations.
Solution:
- Deactivate the license on unused machines
- Contact support to reset activations
- Consider upgrading to Enterprise for more activations
- 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:
- Check the feature matrix in the License Tiers section
- Upgrade your license tier at kyototech.jp/pricing
"Output is watermarked"
Cause: Running in Free mode or with an expired license.
Solution:
- Verify license is activated:
ApiLicense.IsLicensed - Check license status:
ApiLicense.GetLicenseStatus() - Renew if expired
Quantum key generation is slow
Cause: Quantum key generation is computationally intensive.
Solution:
- Pre-generate keys during application idle time
- Use Gen6 for mobile platforms (optimized)
- 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
- Licensing Portal: kyototech.jp/pricing
- Support Contact: kyototech.jp/#contact
- NuGet Package: nuget.org/packages/SaQura
Support Levels
| Tier | Support Level | Response Time |
|---|---|---|
| Free | Community | Best effort |
| Basic | 72 hours | |
| Standard | 48 hours | |
| Pro | Email + Chat | 24 hours |
| Enterprise | Priority + Phone | 4 hours |
Reporting Issues
When contacting support, please include:
- Your license key (first 8 characters only)
- Hardware ID:
ApiLicense.GetHardwareId() - Library version
- Error messages (full stack trace)
- 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.