44 lines
1.8 KiB
Plaintext
44 lines
1.8 KiB
Plaintext
<style>
|
|
body{
|
|
display: grid;
|
|
grid-template: "pass pass" 1.5em
|
|
"main main" auto
|
|
"left right" 2em
|
|
/ auto;
|
|
height: 100%;
|
|
grid-gap: 1em;
|
|
margin: 0;
|
|
background: lightgrey;
|
|
box-sizing: border-box;
|
|
padding: 1em;
|
|
}
|
|
input { grid-area: pass }
|
|
textarea { grid-area: main }
|
|
button:first { grid-area: left }
|
|
button:last { grid-area: right }
|
|
</style>
|
|
<input type="text" placeholder="Enter a password"/>
|
|
<textarea></textarea>
|
|
<button onclick="encrypt()">encrypt</button><button onclick="decrypt()">decrypt</button>
|
|
<script>
|
|
const $ = s=> document.querySelector(s)
|
|
, algo = { name: "AES-GCM", iv: Uint8Array.from([120,1,248,135,62,71,87,156,92,67,155,37]) }
|
|
, $pass = $('input')
|
|
, $text = $('textarea')
|
|
|
|
const encrypt = ()=> {
|
|
crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
|
|
.then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['encrypt']) )
|
|
.then( key=> crypto.subtle.encrypt(algo, key, new TextEncoder().encode($text.value)) )
|
|
.then( ctBuffer=> $text.value = new Uint8Array(ctBuffer).toString().replace(/,/g,'O') )
|
|
.catch( e=> (document.body.style.background = 'red') && setTimeout(o=> document.body.style.background = 'lightgrey', 1000) )
|
|
}
|
|
|
|
const decrypt = ()=> {
|
|
crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
|
|
.then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['decrypt']) )
|
|
.then( key=> crypto.subtle.decrypt(algo, key, Uint8Array.from($text.value.split('O').map(Number)).buffer ) )
|
|
.then( ptBuffer=> $text.value = new TextDecoder().decode(ptBuffer) )
|
|
.catch( e=> (document.body.style.background = 'red') && setTimeout(o=> document.body.style.background = 'lightgrey', 1000) )
|
|
}
|
|
</script> |