1 parent
1e7c84f91f
commit
1111372dc9
4 files changed
+375
-37
No files matched your search
@@ -0,0 +1,2 @@
|
|||||||
|
.protected-backups/
|
||||||
|
page-passwords*.json
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
(function () {
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const form = document.getElementById('unlockForm');
|
||||||
|
const passwordInput = document.getElementById('letterPassword');
|
||||||
|
const statusEl = document.getElementById('unlockStatus');
|
||||||
|
const payloadEl = document.getElementById('encryptedPayload');
|
||||||
|
|
||||||
|
function fromBase64(value) {
|
||||||
|
const binary = atob(value);
|
||||||
|
const bytes = new Uint8Array(binary.length);
|
||||||
|
for (let i = 0; i < binary.length; i += 1) {
|
||||||
|
bytes[i] = binary.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deriveKey(password, salt, iterations) {
|
||||||
|
const baseKey = await crypto.subtle.importKey(
|
||||||
|
'raw',
|
||||||
|
encoder.encode(password),
|
||||||
|
'PBKDF2',
|
||||||
|
false,
|
||||||
|
['deriveKey']
|
||||||
|
);
|
||||||
|
|
||||||
|
return crypto.subtle.deriveKey(
|
||||||
|
{
|
||||||
|
name: 'PBKDF2',
|
||||||
|
salt,
|
||||||
|
iterations,
|
||||||
|
hash: 'SHA-256'
|
||||||
|
},
|
||||||
|
baseKey,
|
||||||
|
{ name: 'AES-GCM', length: 256 },
|
||||||
|
false,
|
||||||
|
['decrypt']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function unlock(password) {
|
||||||
|
const payload = JSON.parse(payloadEl.textContent);
|
||||||
|
const salt = fromBase64(payload.salt);
|
||||||
|
const iv = fromBase64(payload.iv);
|
||||||
|
const ciphertext = fromBase64(payload.ciphertext);
|
||||||
|
const key = await deriveKey(password, salt, payload.iterations);
|
||||||
|
const plaintext = await crypto.subtle.decrypt(
|
||||||
|
{ name: 'AES-GCM', iv },
|
||||||
|
key,
|
||||||
|
ciphertext
|
||||||
|
);
|
||||||
|
|
||||||
|
return decoder.decode(plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
form.addEventListener('submit', async event => {
|
||||||
|
event.preventDefault();
|
||||||
|
const password = passwordInput.value;
|
||||||
|
if (!password) {
|
||||||
|
statusEl.textContent = '请输入密码。';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusEl.textContent = '正在解锁...';
|
||||||
|
form.querySelector('button').disabled = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const html = await unlock(password);
|
||||||
|
document.open();
|
||||||
|
document.write(html);
|
||||||
|
document.close();
|
||||||
|
} catch (error) {
|
||||||
|
statusEl.textContent = '密码不正确,或页面密文已损坏。';
|
||||||
|
form.querySelector('button').disabled = false;
|
||||||
|
passwordInput.select();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}());
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>多彩场景信函样例</title>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Zhi+Mang+Xing&display=swap" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
|
||||||
<link rel="stylesheet" href="../css/notice-banner.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="letter-container theme-campus">
|
|
||||||
|
|
||||||
<h2 class="salutation">亲爱的王子玉:</h2>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<p>好久不见!最近过得怎么样?</p>
|
|
||||||
<p>转眼间夏天就要到了,还记得那时候我们一起在操场上挥洒汗水、在教室里畅谈未来的日子吗?那段时光,真的就像昨天刚发生一样。</p>
|
|
||||||
<p>这次致信,是想告诉你一个好消息。下周六我要举办一个久违的聚会,希望你一定要来!哪怕只是聊聊天,喝杯茶,也是极好的。时光易逝,友情常驻。愿你每天都充满活力,事事顺心!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="closing">
|
|
||||||
<p class="wish-prefix">此致</p>
|
|
||||||
<p class="wish-suffix">敬礼!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
<p class="signature">[您的署名]</p>
|
|
||||||
<p class="date">2026年3月25日</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script defer src="../js/notice-banner.js?v=20260614"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loaded 3 of 4 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user