目 录CONTENT

文章目录

一种简单的加密文章实现(2)

这一次使用纯粹使用前端来加密内容,优点是部署方便,不用折腾后端和数据库,缺点是加密不灵活,如果要修改密钥需要重新生成密文。

首先是加密代码,为了方便测试,同时加入了解密功能,你可以在本地打开这个html文件使用:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>加密内容查看器</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            margin: 0;
            padding: 20px;
            background: inherit;
        }
        .container {
            width: 100%;
            max-width: 100%;
            padding: 20px;
            box-sizing: border-box;
            background: inherit;
        }
        .section {
            margin-bottom: 30px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
            background: inherit;
        }
        textarea {
            width: 100%;
            height: 100px;
            margin: 10px 0;
            padding: 8px;
            box-sizing: border-box;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: inherit;
        }
        input {
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-right: 10px;
            font-size: 16px;
            background: inherit;
        }
        button {
            padding: 8px 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            word-break: break-all;
            background: inherit;
        }
        .error {
            color: #ff4444;
            margin-top: 10px;
        }

        /* 响应式布局 */
        @media screen and (max-width: 768px) {
            body {
                padding: 10px;
            }
            .container {
                padding: 10px;
            }
            .section {
                padding: 15px;
            }
            input {
                width: 100%;
                margin: 10px 0;
            }
            button {
                width: 100%;
                margin: 10px 0;
            }
        }

        /* 超宽屏幕优化 */
        @media screen and (min-width: 1200px) {
            .container {
                max-width: 1200px;
                margin: 0 auto;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- 加密部分 -->
        <div class="section">
            <h3>加密内容</h3>
            <div>
                <textarea id="content-to-encrypt" placeholder="输入要加密的内容"></textarea>
            </div>
            <div>
                <input type="password" id="encrypt-password" placeholder="设置加密密码">
                <button onclick="encryptContent()">加密</button>
            </div>
            <div class="result" id="encrypted-result"></div>
        </div>

        <!-- 解密部分 -->
        <div class="section">
            <h3>解密内容</h3>
            <div>
                <textarea id="content-to-decrypt" placeholder="输入加密后的内容"></textarea>
            </div>
            <div>
                <input type="password" id="decrypt-password" placeholder="输入解密密码">
                <button onclick="decryptContent()">解密</button>
            </div>
            <div id="decrypt-error" class="error"></div>
            <div class="result" id="decrypted-result"></div>
        </div>
    </div>

    <script>
        function encryptContent() {
            const content = document.getElementById('content-to-encrypt').value;
            const password = document.getElementById('encrypt-password').value;
            
            if (!content || !password) {
                alert('请输入内容和密码');
                return;
            }
            try {
                const encrypted = CryptoJS.AES.encrypt(content, password).toString();
                document.getElementById('encrypted-result').textContent = encrypted;
                document.getElementById('content-to-decrypt').value = encrypted;
            } catch (e) {
                alert('加密失败:' + e.message);
            }
        }

        function decryptContent() {
            const encryptedText = document.getElementById('content-to-decrypt').value;
            const password = document.getElementById('decrypt-password').value;
            const errorDiv = document.getElementById('decrypt-error');
            const resultDiv = document.getElementById('decrypted-result');
            
            if (!encryptedText || !password) {
                errorDiv.textContent = '请输入加密内容和密码';
                return;
            }
            try {
                const decrypted = CryptoJS.AES.decrypt(encryptedText, password).toString(CryptoJS.enc.Utf8);
                
                if (decrypted) {
                    resultDiv.textContent = decrypted;
                    errorDiv.textContent = '';
                } else {
                    errorDiv.textContent = '解密失败:密码错误或内容格式不正确';
                    resultDiv.textContent = '';
                }
            } catch (e) {
                errorDiv.textContent = '解密失败:' + e.message;
                resultDiv.textContent = '';
            }
        }

        document.getElementById('decrypt-password').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                decryptContent();
            }
        });
    </script>
</body>
</html>

效果如下:

加密内容查看器

加密内容

解密内容

然后把加密后的密文放入前端中(替换位置在163行,支持markdown渲染):

<div class="encrypted-article-container">
    <div id="passwordSection" class="ea-password-section">
        <div class="ea-input-group">
            <input type="password" id="passwordInput" class="ea-password-input" placeholder="请输入密码" autocomplete="off">
            <button onclick="verifyPassword()" class="ea-button">验证密码</button>
        </div>
        <div id="errorMessage" class="ea-error-message"></div>
    </div>
    <div id="articleContent" class="ea-article-content">
        <div id="articleBody" class="ea-markdown-content"></div>
    </div>

    <style>
        .encrypted-article-container {
            font-family: -apple-system, BlinkMacSystemFont, 'Microsoft YaHei', sans-serif;
            width: 100%;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            box-sizing: border-box;
        }

        .ea-password-section {
            max-width: 600px;
            margin: 20px auto;
            padding: 20px;
            text-align: center;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .ea-input-group {
            display: flex;
            gap: 10px;
            justify-content: center;
            flex-wrap: wrap;
        }

        .ea-password-input {
            padding: 12px 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
            width: 250px;
            font-size: 16px;
            background: #fff;
            transition: border-color 0.3s;
        }

        .ea-password-input:focus {
            outline: none;
            border-color: #4CAF50;
            box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
        }

        .ea-button {
            padding: 12px 24px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: transform 0.2s, filter 0.2s;
        }

        .ea-button:hover {
            filter: brightness(110%);
            transform: translateY(-1px);
        }

        .ea-button:active {
            transform: translateY(0);
        }

        .ea-error-message {
            color: #dc3545;
            margin-top: 10px;
            padding: 8px;
            border-radius: 4px;
            display: none;
            animation: ea-fadeIn 0.3s ease;
        }

        .ea-article-content {
            width: 100%;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            opacity: 0;
            display: none;
            transition: opacity 0.5s ease;
        }

        .ea-article-content.visible {
            opacity: 1;
        }

        .ea-markdown-content {
            line-height: 1.8;
            width: 100%;
            max-width: 100%;
            margin: 0 auto;
        }

        @keyframes ea-fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        @media screen and (max-width: 768px) {
            .ea-input-group {
                flex-direction: column;
                align-items: center;
            }

            .ea-password-input, 
            .ea-button {
                width: 100%;
                max-width: 300px;
            }
        }
    </style>

    <script type="module">
        import { marked } from 'https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js';
        window.marked = marked;
        marked.setOptions({
            breaks: true,
            gfm: true,
            sanitize: true
        });
    </script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
    <script>
        class ArticleDecryptor {
            constructor() {
                this.setupEventListeners();
            }

            setupEventListeners() {
                document.getElementById('passwordInput').addEventListener('keypress', (e) => {
                    if (e.key === 'Enter') {
                        this.verifyPassword();
                    }
                });
            }

            showError(message) {
                const errorElement = document.getElementById('errorMessage');
                errorElement.textContent = message;
                errorElement.style.display = 'block';

                setTimeout(() => {
                    errorElement.style.display = 'none';
                }, 3000);

                if (message.includes('密码错误')) {
                    const passwordInput = document.getElementById('passwordInput');
                    passwordInput.value = '';
                    passwordInput.focus();
                }
            }

            showArticle(content) {
                const passwordSection = document.getElementById('passwordSection');
                const articleContent = document.getElementById('articleContent');
                const articleBody = document.getElementById('articleBody');

                passwordSection.style.display = 'none';

                try {
                    if (typeof window.marked === 'undefined') {
                        articleBody.textContent = content;
                    } else {
                        articleBody.innerHTML = window.marked.parse(content);
                    }
                } catch (error) {
                    console.error('Markdown 渲染错误:', error);
                    articleBody.textContent = content;
                }

                articleContent.style.display = 'block';
                setTimeout(() => {
                    articleContent.classList.add('visible');
                }, 10);
            }

            verifyPassword() {
                const password = document.getElementById('passwordInput').value.trim();
                if (!password) {
                    this.showError('请输入密码');
                    return;
                }

                // 这里替换为实际的加密内容
                const encryptedContent = "" 
              // 你的加密内容

                try {
                    const decrypted = CryptoJS.AES.decrypt(encryptedContent, password).toString(CryptoJS.enc.Utf8);
                    if (decrypted) {
                        this.showArticle(decrypted);
                    } else {
                        this.showError('密码错误,请重试');
                    }
                } catch (e) {
                    this.showError('密码错误,请重试');
                }
            }
        }

        // 初始化
        window.decryptor = new ArticleDecryptor();
        window.verifyPassword = () => window.decryptor.verifyPassword();
    </script></div>

效果演示(密码2025):

加密文章访问

0

评论区