├── Backend ├── crypto │ ├── __init__.py │ ├── utils.py │ ├── decryptor.py │ └── encryptor.py ├── requirements.txt ├── start_api.py ├── README.md ├── API_DOCS.md ├── test_api.py └── api.py ├── original text.txt ├── decrypted.txt ├── encrypted.txt ├── Frontend ├── vite.config.js ├── src │ ├── main.jsx │ ├── index.css │ ├── services │ │ └── api.js │ ├── components │ │ ├── ResultDisplay.jsx │ │ ├── DecryptForm.jsx │ │ └── EncryptForm.jsx │ ├── assets │ │ └── react.svg │ ├── App.jsx │ └── App.css ├── .gitignore ├── index.html ├── package.json ├── README.md ├── eslint.config.js └── public │ └── vite.svg ├── .github ├── ISSUE_TEMPLATE │ ├── -feature-.md │ ├── -bug-.md │ └── -ui-enhancement-.md └── pull_request_template.md ├── CONTRIBUTING.md ├── .gitignore ├── LICENSE.md ├── SECURITY.md ├── Code of Conduct.md ├── README.md ├── static └── styles.css ├── app.py └── templates └── index.html /Backend/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /original text.txt: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /decrypted.txt: -------------------------------------------------------------------------------- 1 | Hi, My name is Harsh Raj -------------------------------------------------------------------------------- /encrypted.txt: -------------------------------------------------------------------------------- 1 | 122 48 55 92 52 64 92 53 1 117 47 92 48 46 92 122 1 138 46 57 92 99 1 10 -------------------------------------------------------------------------------- /Backend/requirements.txt: -------------------------------------------------------------------------------- 1 | cryptography>=41.0.0 2 | flask>=2.3.0 3 | flask-cors>=4.0.0 4 | requests>=2.31.0 -------------------------------------------------------------------------------- /Frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /Frontend/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.jsx' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /Frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/-feature-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "[FEATURE]" 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Proposed Solution** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here, If any. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/-bug-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "[BUG]" 3 | about: Create a report to help us improve 4 | title: "[BUG] \U0001F41B" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Expected behavior** 14 | A clear and concise description of what you expected to happen. 15 | 16 | **Screenshots** 17 | If applicable, add screenshots to help explain your problem. 18 | 19 | **Proposed Solution** 20 | Add any other context about the problem here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/-ui-enhancement-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "[UI Enhancement]" 3 | about: Describe this issue template's purpose here. 4 | title: "[UI Enhancement]" 5 | labels: enhancement 6 | assignees: Dru-429 7 | 8 | --- 9 | 10 | **Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Proposed Solution** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here, If any. 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to RSA Encryption/Decryption Tool 2 | 3 | Thank you for your interest in contributing to this project! We welcome contributions from everyone, whether you're fixing bugs, improving documentation, or suggesting new features. 4 | 5 | ## How to Contribute 6 | 7 | ### Reporting Issues 8 | - If you find a bug or have a feature request, please [open an issue](https://github.com/yourusername/rsa-tool/issues). 9 | - Clearly describe the problem or suggestion, including steps to reproduce if it's a bug. 10 | - Include information about your environment (OS, Python version, etc.). 11 | -------------------------------------------------------------------------------- /Frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pycrypt-frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.11.0", 14 | "lucide-react": "^0.526.0", 15 | "react": "^19.1.0", 16 | "react-dom": "^19.1.0" 17 | }, 18 | "devDependencies": { 19 | "@eslint/js": "^9.30.1", 20 | "@types/react": "^19.1.8", 21 | "@types/react-dom": "^19.1.6", 22 | "@vitejs/plugin-react": "^4.6.0", 23 | "eslint": "^9.30.1", 24 | "eslint-plugin-react-hooks": "^5.2.0", 25 | "eslint-plugin-react-refresh": "^0.4.20", 26 | "globals": "^16.3.0", 27 | "vite": "^7.0.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Frontend/src/index.css: -------------------------------------------------------------------------------- 1 | /* Minimal global styles - main styling is in App.css */ 2 | :root { 3 | font-synthesis: none; 4 | text-rendering: optimizeLegibility; 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | -webkit-text-size-adjust: 100%; 8 | } 9 | 10 | /* Remove default button styles that might interfere */ 11 | button { 12 | font-family: inherit; 13 | } 14 | 15 | /* Ensure full height layout */ 16 | html, body, #root { 17 | height: 100%; 18 | margin: 0; 19 | padding: 0; 20 | } 21 | 22 | /* Custom scrollbar styling */ 23 | ::-webkit-scrollbar { 24 | width: 8px; 25 | } 26 | 27 | ::-webkit-scrollbar-track { 28 | background: #f1f5f9; 29 | } 30 | 31 | ::-webkit-scrollbar-thumb { 32 | background: #cbd5e1; 33 | border-radius: 4px; 34 | } 35 | 36 | ::-webkit-scrollbar-thumb:hover { 37 | background: #94a3b8; 38 | } 39 | -------------------------------------------------------------------------------- /Frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. 13 | -------------------------------------------------------------------------------- /Frontend/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import { defineConfig, globalIgnores } from 'eslint/config' 6 | 7 | export default defineConfig([ 8 | globalIgnores(['dist']), 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | extends: [ 12 | js.configs.recommended, 13 | reactHooks.configs['recommended-latest'], 14 | reactRefresh.configs.vite, 15 | ], 16 | languageOptions: { 17 | ecmaVersion: 2020, 18 | globals: globals.browser, 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | ecmaFeatures: { jsx: true }, 22 | sourceType: 'module', 23 | }, 24 | }, 25 | rules: { 26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], 27 | }, 28 | }, 29 | ]) 30 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## 📝 Pull Request Summary 2 | 3 | 4 | 5 | ## 📌 Related Issue 6 | 7 | Fixes: # 8 | Closes: # 9 | 10 | 11 | ## 🔍 Type of Change 12 | 13 | Please check the relevant option(s): 14 | 15 | - [ ] 🐞 Bug fix 16 | - [ ] ✨ Feature 17 | - [ ] 📝 Documentation 18 | - [ ] 🎨 UI enhancement 19 | 20 | ## 💡 Description of Changes 21 | 22 | 23 | 24 | ## 📸 Screenshots (if applicable) 25 | 26 | 27 | 28 | ## ✅ Checklist 29 | 30 | - [ ] I have tested these changes locally. 31 | - [ ] I have added relevant documentation/comments. 32 | - [ ] My code follows the style guidelines of this project. 33 | - [ ] I have reviewed and updated existing tests or added new ones as needed. 34 | 35 | --- 36 | 37 | Thank you for your contribution! 💙 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | *.manifest 28 | *.spec 29 | 30 | # Installer logs 31 | pip-log.txt 32 | pip-delete-this-directory.txt 33 | 34 | # Unit test / coverage reports 35 | htmlcov/ 36 | .tox/ 37 | .nox/ 38 | .coverage 39 | .coverage.* 40 | .cache 41 | nosetests.xml 42 | coverage.xml 43 | *.cover 44 | .hypothesis/ 45 | .pytest_cache/ 46 | 47 | # GUI-related files 48 | *.log 49 | 50 | # IDEs and editors 51 | .vscode/ 52 | .idea/ 53 | *.sublime-project 54 | *.sublime-workspace 55 | 56 | # Environment variables / virtualenv 57 | .env 58 | .venv 59 | env/ 60 | venv/ 61 | ENV/ 62 | env.bak/ 63 | venv.bak/ 64 | 65 | # MacOS 66 | .DS_Store 67 | 68 | # Windows 69 | Thumbs.db 70 | ehthumbs.db 71 | Desktop.ini 72 | -------------------------------------------------------------------------------- /Backend/crypto/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import hashlib 3 | import hmac 4 | from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC 5 | from cryptography.hazmat.primitives import hashes 6 | from cryptography.hazmat.backends import default_backend 7 | 8 | MAGIC = b'PCRYPT' 9 | VERSION = 1 10 | 11 | backend = default_backend() 12 | 13 | 14 | def generate_salt(): 15 | return os.urandom(16) 16 | 17 | def generate_iv(): 18 | return os.urandom(16) 19 | 20 | def derive_key(password, salt, iterations=200_000): 21 | kdf = PBKDF2HMAC( 22 | algorithm=hashes.SHA256(), 23 | length=32, 24 | salt=salt, 25 | iterations=iterations, 26 | backend=backend 27 | ) 28 | return kdf.derive(password.encode('utf-8')) 29 | 30 | def compute_hmac(key): 31 | return hmac.new(key, digestmod=hashlib.sha256) 32 | 33 | def wipe_file(path): 34 | if not os.path.exists(path): 35 | return 36 | with open(path, 'ba+', buffering=0) as f: 37 | length = f.tell() 38 | f.seek(0) 39 | f.write(os.urandom(length)) 40 | os.remove(path) -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2024 Surjeetsinh Nandkumar Thakur 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Backend/start_api.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | PyCrypt API Startup Script 4 | 5 | Simple script to start the PyCrypt Flask API server with proper configuration. 6 | """ 7 | 8 | import os 9 | import sys 10 | from api import app 11 | 12 | def main(): 13 | """Start the PyCrypt API server""" 14 | print("🔐 Starting PyCrypt API Server...") 15 | print("📡 Server will be available at: http://localhost:5000") 16 | print("📖 API Documentation: Check API_DOCS.md for endpoint details") 17 | print("🔄 CORS enabled for React app integration") 18 | print("💾 Max file size: 16MB") 19 | print() 20 | print("Available endpoints:") 21 | print(" GET /api/health - Health check") 22 | print(" POST /api/encrypt/text - Encrypt text") 23 | print(" POST /api/decrypt/text - Decrypt text") 24 | print(" POST /api/encrypt/file - Encrypt file") 25 | print(" POST /api/decrypt/file - Decrypt file") 26 | print(" POST /api/download/encrypted - Download encrypted file") 27 | print(" POST /api/download/decrypted - Download decrypted file") 28 | print() 29 | print("Press Ctrl+C to stop the server") 30 | print("-" * 50) 31 | 32 | try: 33 | app.run(host='0.0.0.0', port=5000, debug=True) 34 | except KeyboardInterrupt: 35 | print("\n🛑 Server stopped by user") 36 | sys.exit(0) 37 | except Exception as e: 38 | print(f"\n❌ Error starting server: {e}") 39 | sys.exit(1) 40 | 41 | if __name__ == '__main__': 42 | main() -------------------------------------------------------------------------------- /Frontend/src/services/api.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const API_BASE_URL = 'http://localhost:5000/api'; 4 | 5 | // Create axios instance with default config 6 | const apiClient = axios.create({ 7 | baseURL: API_BASE_URL, 8 | timeout: 10000, 9 | headers: { 10 | 'Content-Type': 'application/json', 11 | }, 12 | }); 13 | 14 | // API service functions 15 | export const pycryptAPI = { 16 | // Health check 17 | healthCheck: async () => { 18 | try { 19 | const response = await apiClient.get('/health'); 20 | return { success: true, data: response.data }; 21 | } catch (error) { 22 | return { success: false, error: error.message }; 23 | } 24 | }, 25 | 26 | // Encrypt text 27 | encryptText: async (text, password, hint = '') => { 28 | try { 29 | const response = await apiClient.post('/encrypt/text', { 30 | text, 31 | password, 32 | hint: hint || undefined 33 | }); 34 | return { success: true, data: response.data }; 35 | } catch (error) { 36 | const errorMessage = error.response?.data?.error || error.message; 37 | return { success: false, error: errorMessage }; 38 | } 39 | }, 40 | 41 | // Decrypt text 42 | decryptText: async (encryptedContent, password) => { 43 | try { 44 | const response = await apiClient.post('/decrypt/text', { 45 | encrypted_content: encryptedContent, 46 | password 47 | }); 48 | return { success: true, data: response.data }; 49 | } catch (error) { 50 | const errorMessage = error.response?.data?.error || error.message; 51 | return { success: false, error: errorMessage }; 52 | } 53 | } 54 | }; 55 | 56 | export default pycryptAPI; -------------------------------------------------------------------------------- /Backend/crypto/decryptor.py: -------------------------------------------------------------------------------- 1 | import os 2 | from .utils import derive_key, compute_hmac, MAGIC, VERSION 3 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | CHUNK_SIZE = 64 * 1024 7 | 8 | HEADER_SIZE = len(MAGIC) + 1 + 16 + 16 + 32 # magic, version, salt, iv, hmac 9 | 10 | def decrypt_file(infile, password, overwrite=False): 11 | with open(infile, 'rb') as fin: 12 | magic = fin.read(len(MAGIC)) 13 | if magic != MAGIC: 14 | raise ValueError('Invalid file format (magic bytes mismatch)') 15 | version = fin.read(1)[0] 16 | salt = fin.read(16) 17 | iv = fin.read(16) 18 | hmac_expected = fin.read(32) 19 | hint = fin.read(32) 20 | key = derive_key(password, salt) 21 | backend = default_backend() 22 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 23 | decryptor = cipher.decryptor() 24 | hmac_ctx = compute_hmac(key) 25 | outfile = infile.replace('.enc', '.dec') 26 | if os.path.exists(outfile) and not overwrite: 27 | raise FileExistsError(f'Output file {outfile} exists. Use --overwrite to replace.') 28 | with open(outfile, 'wb') as fout: 29 | while True: 30 | chunk = fin.read(CHUNK_SIZE) 31 | if not chunk: 32 | break 33 | hmac_ctx.update(chunk) 34 | decrypted = decryptor.update(chunk) 35 | fout.write(decrypted) 36 | decrypted = decryptor.finalize() 37 | fout.write(decrypted) 38 | hmac_actual = hmac_ctx.digest() 39 | if hmac_actual != hmac_expected: 40 | os.remove(outfile) 41 | raise ValueError('HMAC verification failed. File may be tampered or password is incorrect.') 42 | return outfile -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # 🔐 Security Policy 2 | 3 | Thank you for helping us make this project better and more secure! 4 | We take security seriously and appreciate your efforts to responsibly disclose vulnerabilities. 5 | 6 | --- 7 | 8 | ## 📅 Supported Versions 9 | 10 | We currently maintain the latest version of the project. Please make sure you're using the latest release before reporting issues. 11 | 12 | | Version | Supported | 13 | | ------- | --------- | 14 | | Latest | ✅ | 15 | | Older | ❌ | 16 | 17 | --- 18 | 19 | ## 📢 Reporting a Vulnerability 20 | 21 | If you discover a vulnerability in this project, we ask you to follow responsible disclosure practices: 22 | 23 | 1. **Do not open a public GitHub issue.** 24 | 2. Instead, please contact us **privately** via email at: 25 | 26 | 📩 **tsurjeet143@gmail.com** 27 | 28 | 3. Include as much detail as possible: 29 | - Description of the vulnerability 30 | - Steps to reproduce 31 | - Potential impact 32 | - Suggested fix (optional but helpful) 33 | 34 | --- 35 | 36 | ## ✅ Scope 37 | 38 | You may report vulnerabilities related to: 39 | 40 | - Code injection (e.g., XSS, command injection) 41 | - Sensitive data exposure 42 | - Authorization or authentication issues 43 | - Malicious file uploads 44 | - Any functionality that compromises user data or system integrity 45 | 46 | ❌ Please do not report: 47 | 48 | - UI/UX suggestions 49 | - Typos or minor styling issues 50 | - Outdated dependencies without known vulnerabilities 51 | 52 | --- 53 | 54 | ## 🕒 Response Timeline 55 | 56 | We aim to respond to all valid security reports **within 48 hours**. 57 | Once confirmed, we will work on a fix and release a patch as soon as possible, crediting the reporter (if they wish). 58 | 59 | --- 60 | 61 | ## 🙏 Thanks 62 | 63 | Thanks for helping us protect our users and improve the open-source ecosystem! 64 | Your efforts make this project safer and better for everyone. ❤️ 65 | -------------------------------------------------------------------------------- /Backend/crypto/encryptor.py: -------------------------------------------------------------------------------- 1 | import os 2 | from .utils import generate_salt, generate_iv, derive_key, compute_hmac, MAGIC, VERSION 3 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 4 | from cryptography.hazmat.backends import default_backend 5 | 6 | CHUNK_SIZE = 64 * 1024 7 | 8 | HEADER_SIZE = len(MAGIC) + 1 + 16 + 16 + 32 # magic, version, salt, iv, hmac 9 | 10 | def encrypt_file(infile, password, hint=None, overwrite=False): 11 | if not password: 12 | raise ValueError('Password must not be empty') 13 | salt = generate_salt() 14 | iv = generate_iv() 15 | key = derive_key(password, salt) 16 | backend = default_backend() 17 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 18 | encryptor = cipher.encryptor() 19 | hmac_ctx = compute_hmac(key) 20 | 21 | outfile = infile + '.enc' 22 | if os.path.exists(outfile) and not overwrite: 23 | raise FileExistsError(f'Output file {outfile} exists. Use --overwrite to replace.') 24 | 25 | with open(infile, 'rb') as fin, open(outfile, 'wb') as fout: 26 | fout.write(MAGIC) 27 | fout.write(bytes([VERSION])) 28 | fout.write(salt) 29 | fout.write(iv) 30 | fout.write(b'\x00' * 32) # Placeholder for HMAC 31 | if hint: 32 | fout.write(hint.encode('utf-8')[:32].ljust(32, b'\x00')) 33 | else: 34 | fout.write(b'\x00' * 32) 35 | total_data = b'' 36 | while True: 37 | chunk = fin.read(CHUNK_SIZE) 38 | if not chunk: 39 | break 40 | if len(chunk) % 16 != 0: 41 | pad_len = 16 - (len(chunk) % 16) 42 | chunk += bytes([pad_len]) * pad_len 43 | encrypted = encryptor.update(chunk) 44 | fout.write(encrypted) 45 | hmac_ctx.update(encrypted) 46 | total_data += encrypted 47 | encrypted = encryptor.finalize() 48 | fout.write(encrypted) 49 | hmac_ctx.update(encrypted) 50 | total_data += encrypted 51 | hmac_digest = hmac_ctx.digest() 52 | fout.seek(len(MAGIC) + 1 + 16 + 16) 53 | fout.write(hmac_digest) 54 | return outfile -------------------------------------------------------------------------------- /Frontend/src/components/ResultDisplay.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Copy, Check, AlertCircle, Shield, Info } from 'lucide-react'; 3 | 4 | const ResultDisplay = ({ result, error }) => { 5 | const [copied, setCopied] = useState(false); 6 | 7 | const handleCopy = async () => { 8 | try { 9 | await navigator.clipboard.writeText(result.content); 10 | setCopied(true); 11 | setTimeout(() => setCopied(false), 2000); 12 | } catch (err) { 13 | console.error('Failed to copy text:', err); 14 | } 15 | }; 16 | 17 | if (error) { 18 | return ( 19 |
20 |
21 | 22 | Error 23 |
24 |
25 |

{error}

26 |
27 |
28 | ); 29 | } 30 | 31 | if (!result) { 32 | return null; 33 | } 34 | 35 | return ( 36 |
37 |
38 | 39 | 40 | {result.type === 'encrypted' ? 'Encrypted Content' : 'Decrypted Content'} 41 | 42 | 50 |
51 | 52 |
53 | 66 |
67 |
68 | 69 | 70 |
71 | 72 | 73 | 81 | 82 |
83 | 84 | 85 |
86 |
87 |

Decrypt Message

88 |
89 | 90 | 91 |
92 |
93 | 94 | 95 |
96 |
97 | 98 | 99 |
100 |
101 | 102 | 103 |
104 | 105 | 106 | 114 |
115 |
116 | 117 |
118 |
119 |

Caesar Cipher

120 |
121 | 122 | 123 |
124 |
125 | 126 | 127 |
128 |
129 | 130 | 131 |
132 |
133 | 134 | 135 |
136 |
137 | 138 |
139 | 140 | 365 | 366 | --------------------------------------------------------------------------------