Thanks to visit codestin.com
Credit goes to lib.rs

13 releases

0.1.13 Sep 26, 2025
0.1.12 Sep 25, 2025

#1408 in Cryptography

Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App

642 downloads per month
Used in logcrypt

MIT license

51KB
842 lines

URICrypt

A Rust library for encrypting URIs while preserving their hierarchical structure and common prefixes.

Features

  • Prefix-Preserving Encryption: URIs with shared paths maintain identical encrypted prefixes, enabling efficient caching and storage
  • Plaintext Scheme: URI schemes (like https://) remain unencrypted for protocol identification
  • Path-Only Support: Can encrypt paths without schemes (e.g., /path/to/file)
  • Deterministic Encryption: Same inputs always produce the same encrypted output
  • URL-Safe Output: Generates clean URLs without padding characters using base64 URL-safe encoding
  • Authenticated Encryption: Each component includes a 16-byte SIV for tamper detection

Installation

Add this to your Cargo.toml:

[dependencies]
uricrypt = "0.1"

Usage

Basic Example

use uricrypt::{encrypt_uri, decrypt_uri};

fn main() {
    let uri = "https://example.com/api/v1/users";
    let secret_key = b"your-secret-key-min-32-bytes-recommended";
    let context = b"MyApp-v1.0";

    // Encrypt the URI (scheme remains plaintext)
    let encrypted = encrypt_uri(uri, secret_key, context);
    println!("Encrypted: {}", encrypted);
    // Output: https://<base64-encoded-encrypted-components>

    // Decrypt it back
    let decrypted = decrypt_uri(&encrypted, secret_key, context).unwrap();
    assert_eq!(uri, decrypted);

    // Also works with path-only URIs
    let path = "/api/v1/users";
    let encrypted_path = encrypt_uri(path, secret_key, context);
    println!("Encrypted path: {}", encrypted_path);
    // Output: /<base64-encoded-encrypted-path>
}

Prefix Preservation

URIs sharing common paths will have identical encrypted prefixes:

let key = b"secret-key";
let ctx = b"app-context";

let uri1 = "https://api.example.com/v1/users/123";
let uri2 = "https://api.example.com/v1/users/456";
let uri3 = "https://api.example.com/v2/posts";

let enc1 = encrypt_uri(uri1, key, ctx);
let enc2 = encrypt_uri(uri2, key, ctx);
let enc3 = encrypt_uri(uri3, key, ctx);

// All three start with "https://" (plaintext scheme)
// enc1 and enc2 share the same encrypted prefix for "api.example.com/v1/users/"
// All three share the encrypted prefix for "api.example.com/"

API Reference

encrypt_uri

pub fn encrypt_uri(uri: &str, secret_key: &[u8], context: &[u8]) -> String

Encrypts a URI while preserving its hierarchical structure and keeping the scheme in plaintext.

Parameters:

  • uri: The URI to encrypt (with or without scheme)
  • secret_key: Secret key for encryption (use at least 32 bytes)
  • context: Additional context for domain separation (e.g., app version)

Returns:

  • For URIs with scheme: Plaintext scheme followed by encrypted components
  • For path-only URIs: '/' followed by encrypted path components

decrypt_uri

pub fn decrypt_uri(
    encrypted_uri: &str,
    secret_key: &[u8],
    context: &[u8],
) -> Result<String, String>

Decrypts a URI encrypted with encrypt_uri.

Parameters:

  • encrypted_uri: The encrypted URI (with plaintext scheme or path-only format)
  • secret_key: Same secret key used for encryption
  • context: Same context used for encryption

Returns: Ok(String) with the original URI, or Err(String) if authentication fails

Security Considerations

  • Key Management: Use a cryptographically secure random key of at least 16 bytes
  • Key Validation: The library validates that key halves are not identical to prevent weak keys
  • Context Binding: The context parameter provides domain separation - use it to bind encryption to specific applications or versions
  • Deterministic: This is deterministic encryption - identical URIs encrypted with the same key/context produce identical ciphertexts
  • Authentication: Each URI component includes a 16-byte authentication tag (SIV) that prevents tampering
  • Accumulated State: Each component's SIV is computed from the accumulated hasher state of all previous components
  • Plaintext Scheme: URI schemes remain unencrypted for protocol identification
  • Algorithm: Uses TurboShake128 (SHA-3 family) for key derivation and stream generation with domain separation

Use Cases

  • Privacy-Preserving Caching: Cache encrypted URLs while maintaining cache hierarchy
  • Log Anonymization: Store and analyze sensitive URLs in logs without exposing actual endpoints
  • Compliant Data Storage: Meet data residency requirements while maintaining URL structure

Dependencies

~1.5MB
~22K SLoC