1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="description" content="AES-256 Encryption Example">
<title>Secure Paste</title>
<link rel="icon" href="./favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="./pico.min.css">
</head>
<body>
<main class="container">
<h1>paste-cgi</h1>
<form id="cryptoForm">
<h3 id="title">Title</h3>
<div id="passwordField" style="display: none;">
<label for="password">Password</label>
<input type="password" id="password" placeholder="Enter your password" />
</div>
<button type="button" id="decryptBtn" onclick="handleDecrypt()" style="display: none;">Decrypt</button>
</form>
<div id="pasteUrlSection" style="display: none;">
<h3>Paste</h3>
<textarea id="decryptedOutput" rows="5" readonly></textarea>
<button type="button" onclick="copyPaste()">Copy</button>
</div>
</main>
<script>
let globalData;
const pasteTypeConstant = "pasteType";
const passwordFieldConstant = "passwordField";
const passwordTypeConstant = "password";
const decryptButtonConstant = "decryptBtn";
const plainTypeConstant = "plain";
const titleConstant = "title";
const expirationConstant = "expiration";
const plaintextConstant = "plaintext";
const decryptedOutputConstant = "decryptedOutput"
const pasteUrlSectionConstant = "pasteUrlSection"
window.onload = async function () {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const fetchUrl = `${window.location.origin}/paste?id=${id}`;
try {
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const data = await response.json();
globalData = data;
togglePasteType()
} catch (error) {
alert("NO File Found")
console.error('Error fetching data:', error);
}
};
function copyPaste() {
var copyText = document.getElementById(decryptedOutputConstant);
copyText.select();
copyText.setSelectionRange(0, 99999);
navigator.clipboard.writeText(copyText.value);
}
function togglePasteType() {
const decryptButton = document.getElementById(decryptButtonConstant);
const passwordField = document.getElementById(passwordFieldConstant);
document.getElementById(titleConstant).textContent = globalData.title;
if (globalData.type === passwordTypeConstant) {
passwordField.style.display = 'block';
decryptButton.style.display = 'block';
} else {
decryptButton.style.display = 'none';
passwordField.style.display = 'none';
document.getElementById(decryptedOutputConstant).textContent = globalData.pasted_text
document.getElementById(pasteUrlSectionConstant).style.display = 'block';
}
}
async function deriveKey(password, salt) {
let encodedPassword = new TextEncoder().encode(password);
let baseKey = await window.crypto.subtle.importKey(
"raw",
encodedPassword,
{ name: "PBKDF2" },
false,
["deriveKey"],
);
let derivedKey = await window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 600000,
hash: "SHA-256",
},
baseKey,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"],
);
return derivedKey;
}
async function decryptData(encryptedData, password) {
let { ciphertext, iv, authTag, salt } = encryptedData;
let key = await deriveKey(password, salt);
let dataWithAuthTag = new Uint8Array(ciphertext.length + authTag.length);
dataWithAuthTag.set(ciphertext, 0);
dataWithAuthTag.set(authTag, ciphertext.length);
let decryptedContent = await window.crypto.subtle.decrypt(
{ name: "AES-GCM", iv: iv, tagLength: 128 },
key,
dataWithAuthTag,
);
return new TextDecoder().decode(decryptedContent);
}
async function handleDecrypt() {
let base64 = globalData.pasted_text;
let password = document.getElementById(passwordTypeConstant).value;
if (!base64 || !password) return alert("Enter encrypted text and password.");
try {
let parsed = JSON.parse(atob(base64));
let encryptedData = {
salt: new Uint8Array(Object.values(parsed.salt)),
iv: new Uint8Array(Object.values(parsed.iv)),
authTag: new Uint8Array(Object.values(parsed.authTag)),
ciphertext: new Uint8Array(Object.values(parsed.ciphertext)),
};
let decrypted = await decryptData(encryptedData, password);
document.getElementById("decryptedOutput").value = decrypted;
document.getElementById(pasteUrlSectionConstant).style.display = 'block';
} catch (err) {
document.getElementById("decryptedOutput").value = "❌ Decryption failed.";
}
}
</script>
</body>
</html>
|