{"id":42626777,"url":"https://github.com/rggh/locky-rocks","last_synced_at":"2026-01-29T05:02:38.464Z","repository":{"id":292582912,"uuid":"981326326","full_name":"RGGH/locky-rocks","owner":"RGGH","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-10T21:24:27.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-10T22:25:46.682Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RGGH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-10T21:10:51.000Z","updated_at":"2025-05-10T21:24:30.000Z","dependencies_parsed_at":"2025-05-10T22:35:55.740Z","dependency_job_id":null,"html_url":"https://github.com/RGGH/locky-rocks","commit_stats":null,"previous_names":["rggh/locky-rocks"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RGGH/locky-rocks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RGGH%2Flocky-rocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RGGH%2Flocky-rocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RGGH%2Flocky-rocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RGGH%2Flocky-rocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RGGH","download_url":"https://codeload.github.com/RGGH/locky-rocks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RGGH%2Flocky-rocks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28863009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T22:56:21.783Z","status":"online","status_checked_at":"2026-01-29T02:00:06.714Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-29T05:01:32.182Z","updated_at":"2026-01-29T05:02:38.454Z","avatar_url":"https://github.com/RGGH.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Locky-Rocks: Encrypted Counter with RocksDB [![Rust](https://github.com/RGGH/locky-rocks/actions/workflows/rust.yml/badge.svg)](https://github.com/RGGH/locky-rocks/actions/workflows/rust.yml)\n\nA secure, persistent counter implementation that uses RocksDB for storage and AES-GCM for encryption.\n\n## Overview\n\nLocky-Rocks provides a simple yet secure way to maintain encrypted counters that persist across application restarts. Built on top of RocksDB, it offers:\n\n- **Data Persistence**: Counter values are stored on disk and survive application restarts\n- **Value Encryption**: AES-256-GCM encryption protects counter values from tampering\n- **Atomic Operations**: Reliable increment operations even with concurrent access\n- **Performance**: Optimized for high-throughput counter operations\n\n## Security Features\n\n### Encryption Details\n\n- **Algorithm**: AES-256-GCM (Galois/Counter Mode)\n- **Key Length**: 256-bit encryption key\n- **Authentication**: Built-in authentication with GCM mode\n- **Nonce Handling**: Unique 96-bit (12-byte) nonce generated for each write operation\n\n### Security Properties\n\n1. **Confidentiality**: Counter values are encrypted, preventing unauthorized users from seeing the actual values even if they access the database files.\n\n2. **Integrity and Authentication**: The GCM mode provides built-in authentication, detecting any tampering with the encrypted data.\n\n3. **Freshness**: Each update uses a new random nonce, preventing replay attacks where an attacker might try to replace current values with older encrypted values.\n\n4. **Tamper Evidence**: Any attempt to modify the encrypted data manually (e.g., using a hex editor) will result in authentication failure during decryption.\n\n### Security Level\n\nThis implementation provides:\n\n- **Strong Protection Against Manual Tampering**: The AES-GCM authentication makes it computationally infeasible to modify the encrypted counter value without knowing the encryption key.\n\n- **Targeted Protection**: Rather than encrypting the entire database, this approach encrypts only the sensitive counter values, providing a balance between security and performance.\n\n- **Protection Against Database Inspection**: Even with direct access to the database files, an attacker cannot determine the counter values without the encryption key.\n\n### Security Limitations\n\n- **Key Management**: The encryption key is currently hardcoded in the application. In a production environment, this key should be securely managed (via environment variables, a secure key management service, etc.).\n\n- **Key in Memory**: While running, the encryption key exists in the application's memory space.\n\n- **Metadata Visibility**: While the counter values are encrypted, the counter names (keys) are stored in plaintext within the RocksDB files.\n\n## Usage Example\n\n```rust\nuse locky_rocks::EncryptedCounter;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // Create or open an encrypted counter\n    let counter = EncryptedCounter::new(\"./counter_db\", \"my_secure_counter\")?;\n    \n    // Get the current value\n    println!(\"Current value: {}\", counter.get()?);\n    \n    // Increment counter by 1\n    let new_value = counter.increment()?;\n    println!(\"After increment: {}\", new_value);\n    \n    // Increment by specific amount\n    let new_value = counter.increment_by(5)?;\n    println!(\"After incrementing by 5: {}\", new_value);\n    \n    Ok(())\n}\n```\n\n## Build and Run\n\n```bash\n# Debug build\ncargo build\n\n# Release build with optimizations\ncargo build --release\n\n# Run\ncargo run --release\n```\n\n## Technical Details\n\nThe `EncryptedCounter` stores values in RocksDB as follows:\n\n1. The counter name serves as the key in the RocksDB database\n2. For each value stored:\n   - A fresh 12-byte nonce is generated\n   - The u64 counter value is encrypted using AES-GCM with this nonce\n   - The nonce and encrypted data are concatenated and stored as the value\n\nWhen reading the counter value:\n1. The encrypted data is retrieved from RocksDB using the counter name\n2. The first 12 bytes are extracted as the nonce\n3. The remaining bytes are decrypted using the encryption key and nonce\n4. The decrypted value is converted back to a u64 counter value\n\nThis approach ensures that every update to the counter results in completely different ciphertext, even when incrementing by 1.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frggh%2Flocky-rocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frggh%2Flocky-rocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frggh%2Flocky-rocks/lists"}