HTML+CSS+JavaScript实现的AES加密工具网页应用,包含完整的UI界面和加密/解密功能

荻酷分享:以下是基于HTML+CSS+JavaScript实现的AES加密工具网页应用,包含完整的UI界面和加密/解密功能:

JS加密工具

完整功能:实现AES-256加密/解密功能,包含盐值和IV生成增强安全性

现代化UI:采用渐变色背景、毛玻璃效果卡片和流畅动画

响应式设计:适配不同屏幕尺寸,移动端友好

完整交互:包含密钥显示切换、结果复制、本地保存等功能

安全提示:所有操作在本地完成,不传输数据到服务器

错误处理:完善的错误捕获和用户提示机制

演示效果:

index.html代码如下:

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JS加密工具</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
    <style>
        .gradient-bg {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
    </style>
</head>
<body class="min-h-screen gradient-bg text-gray-100">
    <div class="container mx-auto px-4 py-12">
        <header class="text-center mb-12">
            <h1 class="text-4xl font-bold mb-2">JS加密工具</h1>
            <p class="text-xl opacity-90">基于AES算法的安全加密/解密工具</p>
        </header>

        <main class="max-w-4xl mx-auto">
            <div class="bg-white bg-opacity-10 backdrop-filter backdrop-blur-lg rounded-xl shadow-xl overflow-hidden card-hover">
                <div class="p-6">
                    <div class="flex flex-col md:flex-row gap-6">
                        <div class="flex-1">
                            <div class="mb-6">
                                <label class="block text-sm font-medium mb-2" for="inputText">输入文本</label>
                                <textarea id="inputText" rows="6" class="w-full px-4 py-3 rounded-lg bg-white bg-opacity-20 border border-white border-opacity-30 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:border-transparent placeholder-gray-300" placeholder="请输入要加密/解密的文本..."></textarea>
                            </div>

                            <div class="mb-6">
                                <label class="block text-sm font-medium mb-2" for="secretKey">密钥</label>
                                <div class="relative">
                                    <input type="password" id="secretKey" class="w-full px-4 py-3 rounded-lg bg-white bg-opacity-20 border border-white border-opacity-30 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:border-transparent placeholder-gray-300" placeholder="请输入加密密钥">
                                    <button id="toggleKey" class="absolute right-3 top-3 text-gray-300 hover:text-white">
                                        <i class="far fa-eye"></i>
                                    </button>
                                </div>
                            </div>

                            <div class="flex flex-wrap gap-4 mb-6">
                                <button id="encryptBtn" class="flex-1 bg-purple-600 hover:bg-purple-700 text-white font-medium py-3 px-6 rounded-lg transition duration-300 flex items-center justify-center gap-2">
                                    <i class="fas fa-lock"></i> 加密
                                </button>
                                <button id="decryptBtn" class="flex-1 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-6 rounded-lg transition duration-300 flex items-center justify-center gap-2">
                                    <i class="fas fa-unlock"></i> 解密
                                </button>
                                <button id="clearBtn" class="flex-1 bg-gray-600 hover:bg-gray-700 text-white font-medium py-3 px-6 rounded-lg transition duration-300 flex items-center justify-center gap-2">
                                    <i class="fas fa-trash-alt"></i> 清空
                                </button>
                            </div>
                        </div>

                        <div class="flex-1">
                            <label class="block text-sm font-medium mb-2" for="outputText">结果</label>
                            <textarea id="outputText" rows="6" readonly class="w-full px-4 py-3 rounded-lg bg-white bg-opacity-20 border border-white border-opacity-30 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:border-transparent placeholder-gray-300" placeholder="加密/解密结果将显示在这里..."></textarea>
                            
                            <div class="mt-4 flex gap-4">
                                <button id="copyBtn" class="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition duration-300 flex items-center justify-center gap-2">
                                    <i class="far fa-copy"></i> 复制结果
                                </button>
                                <button id="saveBtn" class="flex-1 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-lg transition duration-300 flex items-center justify-center gap-2">
                                    <i class="far fa-save"></i> 保存到本地
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="mt-8 bg-white bg-opacity-10 backdrop-filter backdrop-blur-lg rounded-xl shadow-xl overflow-hidden card-hover fade-in">
                <div class="p-6">
                    <h2 class="text-xl font-semibold mb-4">使用说明</h2>
                    <ul class="space-y-2 text-sm opacity-90">
                        <li><i class="fas fa-info-circle mr-2"></i> 使用AES-256算法进行加密/解密</li>
                        <li><i class="fas fa-key mr-2"></i> 密钥长度建议至少16个字符</li>
                        <li><i class="fas fa-shield-alt mr-2"></i> 所有操作均在浏览器本地完成,数据不会上传到服务器</li>
                        <li><i class="fas fa-history mr-2"></i> 加密结果包含随机盐值,每次加密结果不同但都能解密</li>
                        <li><i class="fas fa-exclamation-triangle mr-2"></i> 请妥善保管密钥,丢失后将无法解密数据</li>
                    </ul>
                </div>
            </div>
        </main>

        <footer class="mt-16 text-center text-sm opacity-75">
            <p>© 2025 JS加密工具 | 基于CryptoJS实现</p>
        </footer>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 切换密钥可见性
            const toggleKey = document.getElementById('toggleKey');
            const secretKey = document.getElementById('secretKey');
            toggleKey.addEventListener('click', function() {
                if (secretKey.type === 'password') {
                    secretKey.type = 'text';
                    toggleKey.innerHTML = '<i class="far fa-eye-slash"></i>';
                } else {
                    secretKey.type = 'password';
                    toggleKey.innerHTML = '<i class="far fa-eye"></i>';
                }
            });

            // 加密函数
            function encrypt(text, key) {
                if (!text || !key) {
                    alert('请输入文本和密钥');
                    return null;
                }
                
                try {
                    const salt = CryptoJS.lib.WordArray.random(128/8);
                    const iv = CryptoJS.lib.WordArray.random(128/8);
                    const key256Bits = CryptoJS.PBKDF2(key, salt, {
                        keySize: 256/32,
                        iterations: 1000
                    });
                    
                    const encrypted = CryptoJS.AES.encrypt(text, key256Bits, { 
                        iv: iv,
                        padding: CryptoJS.pad.Pkcs7,
                        mode: CryptoJS.mode.CBC
                    });
                    
                    // 组合盐值、IV和加密数据
                    const result = {
                        salt: salt.toString(),
                        iv: iv.toString(),
                        ciphertext: encrypted.toString()
                    };
                    
                    return JSON.stringify(result);
                } catch (error) {
                    console.error('加密错误:', error);
                    alert('加密过程中发生错误');
                    return null;
                }
            }

            // 解密函数
            function decrypt(encryptedData, key) {
                if (!encryptedData || !key) {
                    alert('请输入加密数据和密钥');
                    return null;
                }
                
                try {
                    const data = JSON.parse(encryptedData);
                    const salt = CryptoJS.enc.Hex.parse(data.salt);
                    const iv = CryptoJS.enc.Hex.parse(data.iv);
                    
                    const key256Bits = CryptoJS.PBKDF2(key, salt, {
                        keySize: 256/32,
                        iterations: 1000
                    });
                    
                    const decrypted = CryptoJS.AES.decrypt(data.ciphertext, key256Bits, { 
                        iv: iv,
                        padding: CryptoJS.pad.Pkcs7,
                        mode: CryptoJS.mode.CBC
                    });
                    
                    return decrypted.toString(CryptoJS.enc.Utf8);
                } catch (error) {
                    console.error('解密错误:', error);
                    alert('解密失败,请检查密钥或数据是否正确');
                    return null;
                }
            }

            // 按钮事件绑定
            document.getElementById('encryptBtn').addEventListener('click', function() {
                const inputText = document.getElementById('inputText').value;
                const key = document.getElementById('secretKey').value;
                const encrypted = encrypt(inputText, key);
                if (encrypted) {
                    document.getElementById('outputText').value = encrypted;
                }
            });

            document.getElementById('decryptBtn').addEventListener('click', function() {
                const inputText = document.getElementById('inputText').value;
                const key = document.getElementById('secretKey').value;
                const decrypted = decrypt(inputText, key);
                if (decrypted) {
                    document.getElementById('outputText').value = decrypted;
                }
            });

            document.getElementById('clearBtn').addEventListener('click', function() {
                document.getElementById('inputText').value = '';
                document.getElementById('outputText').value = '';
                document.getElementById('secretKey').value = '';
            });

            document.getElementById('copyBtn').addEventListener('click', function() {
                const outputText = document.getElementById('outputText');
                outputText.select();
                document.execCommand('copy');
                
                // 显示复制成功提示
                const originalText = this.innerHTML;
                this.innerHTML = '<i class="fas fa-check"></i> 已复制';
                setTimeout(() => {
                    this.innerHTML = originalText;
                }, 2000);
            });

            document.getElementById('saveBtn').addEventListener('click', function() {
                const outputText = document.getElementById('outputText').value;
                if (!outputText) {
                    alert('没有可保存的内容');
                    return;
                }
                
                const blob = new Blob([outputText], { type: 'text/plain' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'encrypted_data.txt';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
                
                // 显示保存成功提示
                const originalText = this.innerHTML;
                this.innerHTML = '<i class="fas fa-check"></i> 已保存';
                setTimeout(() => {
                    this.innerHTML = originalText;
                }, 2000);
            });
        });
    </script>
</body>
</html>
相关推荐
excel19 小时前
Vue3 EffectScope 源码解析与理解
前端·javascript·面试
细节控菜鸡20 小时前
【2025最新】ArcGIS for JS 实现地图卷帘效果
开发语言·javascript·arcgis
祈祷苍天赐我java之术21 小时前
Redis 有序集合解析
java·前端·windows·redis·缓存·bootstrap·html
心.c1 天前
一套完整的前端“白屏”问题分析与解决方案(性能优化)
前端·javascript·性能优化·html
俺会hello我的1 天前
舒尔特方格开源
前端·javascript·开源
lbh1 天前
Chrome DevTools 详解(二):Console 面板
前端·javascript·浏览器
wxr06161 天前
部署Spring Boot项目+mysql并允许前端本地访问的步骤
前端·javascript·vue.js·阿里云·vue3·springboot
知识分享小能手1 天前
微信小程序入门学习教程,从入门到精通,WXSS样式处理语法基础(9)
前端·javascript·vscode·学习·微信小程序·小程序·vue
木心操作1 天前
nodejs动态创建sql server表
前端·javascript·sql
一个很帅的帅哥1 天前
Vue中的data为什么是函数?
前端·javascript·vue.js·data