# Rust WebAssembly Cryptography Module This project provides a WebAssembly module written in Rust that offers cryptographic functionality for web applications. ## Features - **Key Space Management** - Password-protected encrypted spaces - Multiple spaces with different passwords - Persistent storage in browser's localStorage - Auto-logout after 15 minutes of inactivity - **Asymmetric Cryptography** - Multiple named ECDSA keypairs - Keypair selection for operations - Message signing - Signature verification - **Symmetric Cryptography** - ChaCha20Poly1305 encryption/decryption - Secure key generation - Password-based encryption ## Prerequisites Before you begin, ensure you have the following installed: - [Rust](https://www.rust-lang.org/tools/install) (1.70.0 or later) - [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) (0.10.0 or later) - [Node.js](https://nodejs.org/) (14.0.0 or later) - A modern web browser that supports WebAssembly ## Project Structure ``` webassembly/ ├── src/ │ ├── api/ # Public API modules │ │ ├── keypair.rs # Public keypair API │ │ ├── mod.rs # API module exports │ │ └── symmetric.rs # Public symmetric encryption API │ ├── core/ # Internal implementation modules │ │ ├── error.rs # Error types and conversions │ │ ├── keypair.rs # Core keypair implementation │ │ ├── mod.rs # Core module exports │ │ └── symmetric.rs # Core symmetric encryption implementation │ ├── tests/ # Test modules │ │ ├── keypair_tests.rs # Tests for keypair functionality │ │ ├── mod.rs # Test module exports │ │ └── symmetric_tests.rs # Tests for symmetric encryption │ └── lib.rs # Main entry point, exports WASM functions ├── www/ │ ├── index.html # Example HTML page │ ├── server.js # Simple HTTP server for testing │ └── js/ │ └── index.js # JavaScript code to load and use the WebAssembly module ├── Cargo.toml # Rust package configuration ├── start.sh # Script to build and run the example └── README.md # This file ``` ## Running the Example The easiest way to run the example is to use the provided start script: ```bash ./start.sh ``` This script will: 1. Build the WebAssembly module using wasm-pack 2. Start a local HTTP server Then open your browser and navigate to http://localhost:8080. ## Building Manually If you prefer to build and run the example manually: 1. Build the WebAssembly module: ```bash wasm-pack build --target web ``` 2. Start the local server: ```bash cd www && npm install && node server.js ``` 3. Open your browser and navigate to http://localhost:8080. ## Running Tests To run the tests: ```bash cargo test ``` ## API Reference ### Key Space Management ```javascript // Create a new key space const result = await wasm.create_key_space("my_space"); if (result === 0) { console.log("Space created successfully"); } // Encrypt the current space with a password const encryptedSpace = await wasm.encrypt_key_space("my_password"); localStorage.setItem("crypto_space_my_space", encryptedSpace); // Decrypt and load a space const storedSpace = localStorage.getItem("crypto_space_my_space"); const decryptResult = await wasm.decrypt_key_space(storedSpace, "my_password"); if (decryptResult === 0) { console.log("Space loaded successfully"); } // Logout (clear current session) wasm.logout(); ``` ### Keypair Operations ```javascript // Create a new keypair in the current space const result = await wasm.create_keypair("my_keypair"); if (result === 0) { console.log("Keypair created successfully"); } // Select a keypair for use const selectResult = await wasm.select_keypair("my_keypair"); if (selectResult === 0) { console.log("Keypair selected successfully"); } // List all keypairs in the current space const keypairs = await wasm.list_keypairs(); console.log("Available keypairs:", keypairs); // Get the public key of the selected keypair const pubKey = await wasm.keypair_pub_key(); // Sign a message with the selected keypair const message = new TextEncoder().encode("Hello, world!"); const signature = await wasm.keypair_sign(message); // Verify a signature with the selected keypair const isValid = await wasm.keypair_verify(message, signature); console.log("Signature valid:", isValid); ``` ### Symmetric Encryption ```javascript // Generate a symmetric key const key = wasm.generate_symmetric_key(); // Encrypt a message const message = new TextEncoder().encode("Secret message"); const ciphertext = await wasm.encrypt_symmetric(key, message); // Decrypt a message const decrypted = await wasm.decrypt_symmetric(key, ciphertext); const decryptedText = new TextDecoder().decode(decrypted); console.log("Decrypted:", decryptedText); // Derive a key from a password const derivedKey = wasm.derive_key_from_password("my_password"); // Encrypt with a password const passwordMessage = new TextEncoder().encode("Password protected message"); const passwordCiphertext = await wasm.encrypt_with_password("my_password", passwordMessage); // Decrypt with a password const passwordDecrypted = await wasm.decrypt_with_password("my_password", passwordCiphertext); const passwordDecryptedText = new TextDecoder().decode(passwordDecrypted); console.log("Password decrypted:", passwordDecryptedText); ``` ## Security Considerations - Key spaces are encrypted using ChaCha20Poly1305 with a key derived from the user's password. - Keypairs are stored in encrypted spaces and persisted in localStorage when the space is saved. - The system implements auto-logout after 15 minutes of inactivity for additional security. - The symmetric encryption uses ChaCha20Poly1305, which provides authenticated encryption. - The nonce for symmetric encryption is generated randomly and appended to the ciphertext. - Password-based key derivation uses SHA-256 (consider using a more secure KDF like Argon2 for production). ## License This project is licensed under the MIT License - see the LICENSE file for details.