-
Notifications
You must be signed in to change notification settings - Fork 0
Security Model & Best Practices
This document outlines the security model of the Oracipher Core library and provides essential best practices for developers. Adhering to these guidelines is critical for building secure applications on top of the library.
The library is designed to be a secure cryptographic kernel, but its overall security relies on a partnership between the library's guarantees and the developer's secure implementation.
A threat model defines what a system is designed to protect against and, just as importantly, what is outside its scope.
Oracipher Core is designed to protect against:
- Network Eavesdropping: All data encrypted by the library is protected by XChaCha20-Poly1305, ensuring confidentiality even if an attacker captures all network traffic.
- Data Tampering (Man-in-the-Middle Attacks): The use of Authenticated Encryption (AEAD) and signed OCSP responses ensures that any modification to encrypted data or certificate status information in transit will be detected, causing the operation to fail.
- Server-Side Data Breaches: If a server storing data encrypted by Oracipher Core is compromised, the data payloads remain secure as the server does not have access to the users' private keys.
- Offline Password Cracking: If a database of password hashes is stolen, the combination of a unique salt per user and the mandatory, system-wide security pepper makes pre-computed rainbow table attacks and low-cost brute-force attacks against the hashes computationally infeasible.
Oracipher Core is NOT designed to protect against:
- Compromised Client Endpoints: The library cannot protect against threats on the user's machine, such as malware, keyloggers, or memory-scraping viruses. The security of the client environment is the developer's responsibility.
-
Insecure Environment Variable Injection: The security of the
HSC_PEPPER_HEXenvironment variable depends on the security of the deployment environment. The library trusts that the environment provides this secret securely. - Compromised Certificate Authority (CA): The entire PKI trust model relies on the integrity of the CA. If the CA's private key is stolen, an attacker can issue fraudulent certificates and impersonate any user.
- Physical Coercion or User Negligence: The library cannot protect against a user being forced to give up their keys or a user mishandling their private key files.
Security is a shared responsibility between the library and the application developer.
The Library's Responsibilities (Our Guarantees):
-
Correct Cryptographic Implementation: We guarantee that the library correctly uses the underlying cryptographic primitives from
libsodiumandOpenSSLaccording to modern best practices. - Secure Internal Memory Management: We guarantee that all internal, long-term secrets (like private keys and the security pepper) are handled exclusively in protected, non-swappable memory and are securely wiped upon release.
- Fail-Closed Policy Enforcement: We guarantee that any ambiguity or failure during a critical security check (like OCSP validation) will result in the operation failing securely.
- Safe API Contract: We provide a clear API that is resistant to common misuse patterns (e.g., automatic nonce management in standard APIs).
The Developer's Responsibilities (Your Obligations):
- Protect Private Keys at Rest: You are responsible for securing user private key files on the filesystem with strict permissions.
-
Securely Manage the Security Pepper: You are responsible for generating, storing, and securely injecting the
HSC_PEPPER_HEXenvironment variable in your production environment. - Check Every Return Code: You are responsible for checking the return value of every library function call and handling failures appropriately by aborting the sensitive operation.
- Secure Your Certificate Authority: You are responsible for the security and operational integrity of your CA, which is the root of your trust model.
-
Handle Plaintext Securely: You are responsible for using the provided secure memory functions (
hsc_secure_alloc/hsc_secure_free) for any sensitive plaintext data your application handles.
The use of a global security pepper is a mandatory, non-negotiable part of the library's KDF security model.
- What It Is: A secret value, unique to your entire service or application, that is mixed with user passwords before they are processed by Argon2id.
- Why It's Critical: It defeats offline attacks on a stolen password hash database. An attacker with the database cannot begin password-guessing or rainbow table attacks without also knowing the pepper. It effectively gives every password in your system a unique, high-entropy secret component that the attacker does not have.
-
How to Manage in Production: The pepper must never be hardcoded or stored in a configuration file alongside the application code. It must be injected into the application's environment at runtime. Secure methods include:
- Container/Orchestration Secrets: Using tools like Docker Secrets, Kubernetes Secrets, or HashiCorp Vault.
- Cloud Provider Secret Managers: Using services like AWS Secrets Manager, Google Cloud Secret Manager, or Azure Key Vault.
-
Generating a Secure Pepper:
# Use OpenSSL to generate a cryptographically secure 32-byte (256-bit) pepper in hex format openssl rand -hex 32
Violating these practices can completely undermine the security guarantees provided by the library.
-
DO: Call
hsc_init()once at the very beginning of yourmainfunction. -
DO: Call
hsc_cleanup()once just before your application exits. -
DO NOT: Call any other library function before
hsc_init()has successfully returnedHSC_OK. -
DO NOT: Forget to call
hsc_cleanup(), as this will leave the security pepper lingering in memory.
-
DO: Check the return value of every function call against
HSC_OK. -
DO NOT: Assume an operation succeeded. Ignoring a failure from a function like
hsc_verify_user_certificateorhsc_aead_decryptcan lead to you trusting an invalid identity or acting on unauthenticated data.
// WRONG - Ignores failure, proceeds with a potentially untrusted key
int ignored_result = hsc_verify_user_certificate(cert, ca, "user");
hsc_extract_public_key_from_cert(cert, public_key); // This is now a dangerous operation
// RIGHT - Aborts on failure
if (hsc_verify_user_certificate(cert, ca, "user") != HSC_OK) {
// Log the error and immediately abort the entire workflow.
return;
}
// It is now safe to trust this certificate and extract the key.
hsc_extract_public_key_from_cert(cert, public_key);The library exposes hsc_secure_alloc and hsc_secure_free for handling sensitive data in your application's memory.
-
DO: Use
hsc_secure_allocto store sensitive plaintext that your application must temporarily handle, such as:- A decapsulated session key.
- The contents of a fully decrypted file before processing.
- A user's password before passing it to
hsc_derive_key_from_password.
-
DO: Call
hsc_secure_freeon the pointer as soon as the sensitive data is no longer needed to minimize its exposure time in memory.
-
DO: Set strict filesystem permissions for private key files (e.g.,
chmod 400 my_user.keyon Linux/macOS). - DO NOT: Store private keys in publicly accessible locations, check them into version control, or embed them directly in application bundles.
- CONSIDER: For high-security environments, store private keys in a Hardware Security Module (HSM).
-
DO NOT: Use
hsc_aead_encrypt_detachedunless absolutely necessary for a specific protocol. If you do, you are responsible for nonce management. Nonce reuse with the same key is a catastrophic failure that destroys confidentiality. Always generate a unique nonce for every encryption usinghsc_random_bytes. -
DO: Prefer the standard
hsc_aead_encryptand stream APIs, which handle nonces safely and automatically.
- Is
hsc_init()called at startup andhsc_cleanup()at shutdown? - Is the
HSC_PEPPER_HEXenvironment variable generated securely and injected into my production environment without being logged or stored in version control? - Am I checking the return code of every Oracipher Core function call against
HSC_OK? - Are my users' private key files protected with strict filesystem permissions (
400or600)? - Is my CA private key secured (preferably offline), and do I have a defined certificate revocation process?
- Am I using
hsc_secure_allocandhsc_secure_freefor all sensitive plaintext my application code handles?