Skip to content

Commit

Permalink
feat(new tool): PGP Encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
sharevb committed Apr 28, 2024
1 parent 9eac9cb commit 3c8dffa
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer';

import { tool as textToUnicode } from './text-to-unicode';
import { tool as safelinkDecoder } from './safelink-decoder';
import { tool as pgpEncryption } from './pgp-encryption';
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
import { tool as numeronymGenerator } from './numeronym-generator';
import { tool as macAddressGenerator } from './mac-address-generator';
Expand Down Expand Up @@ -85,7 +86,20 @@ import { tool as yamlViewer } from './yaml-viewer';
export const toolsByCategory: ToolCategory[] = [
{
name: 'Crypto',
components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker],
components: [
tokenGenerator,
hashText,
bcrypt,
uuidGenerator,
ulidGenerator,
cypher,
bip39,
hmacGenerator,
rsaKeyPairGenerator,
passwordStrengthAnalyser,
pdfSignatureChecker,
pgpEncryption,
],
},
{
name: 'Converter',
Expand Down
12 changes: 12 additions & 0 deletions src/tools/pgp-encryption/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Lock } from '@vicons/tabler';
import { defineTool } from '../tool';

export const tool = defineTool({
name: 'PGP encryption',
path: '/pgp-encryption',
description: 'Encrypt and decrypt text clear text using PGP Keys.',
keywords: ['pgp', 'openpgp', 'encryption', 'cypher', 'encipher', 'crypt', 'decrypt'],
component: () => import('./pgp-encryption.vue'),
icon: Lock,
createdAt: new Date('2024-04-20'),
});
169 changes: 169 additions & 0 deletions src/tools/pgp-encryption/pgp-encryption.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<script setup lang="ts">
import * as openpgp from 'openpgp';
import { computedCatchAsync } from '@/composable/computed/catchedComputed';
const cryptInput = ref('');
const cryptPublicKey = ref('');
const cryptPrivateKey = ref('');
const cryptPrivateKeyPassphrase = ref('');
const [cryptOutput, cryptError] = computedCatchAsync(async () => {
const publicKeyArmored = cryptPublicKey.value;
const privateKeyArmored = cryptPrivateKey.value;
const passphrase = cryptPrivateKeyPassphrase.value;
const text = cryptInput.value;
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
const privateKey = privateKeyArmored !== ''
? await openpgp.decryptKey({
privateKey: await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }),
passphrase,
})
: undefined;
return await openpgp.encrypt({
message: await openpgp.createMessage({ text }),
encryptionKeys: publicKey,
signingKeys: privateKey,
});
}, {
defaultValue: '',
defaultErrorMessage: 'Unable to encrypt your text',
});
const decryptInput = ref('');
const decryptPublicKey = ref('');
const decryptPrivateKey = ref('');
const decryptPrivateKeyPassphrase = ref('');
const [decryptOutput, decryptError] = computedCatchAsync(async () => {
const publicKeyArmored = decryptPublicKey.value;
const privateKeyArmored = decryptPrivateKey.value;
const passphrase = decryptPrivateKeyPassphrase.value;
const encrypted = decryptInput.value;
const publicKey = privateKeyArmored !== '' ? await openpgp.readKey({ armoredKey: publicKeyArmored }) : undefined;
const privateKey = await openpgp.decryptKey({
privateKey: await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }),
passphrase,
});
const message = await openpgp.readMessage({
armoredMessage: encrypted, // parse armored message
});
const { data: decrypted, signatures } = await openpgp.decrypt({
message,
verificationKeys: publicKey, // optional
decryptionKeys: privateKey,
});
if (signatures.length > 0) {
try {
await signatures[0].verified; // throws on invalid signature
}
catch (e: any) {
throw new Error(`Signature could not be verified: ${e.toString()}`);
}
}
return decrypted;
}, {
defaultValue: '',
defaultErrorMessage: 'Unable to encrypt your text',
});
</script>

<template>
<div>
<c-card title="Encrypt">
<div flex gap-3>
<c-input-text
v-model:value="cryptInput"
label="Your text:"
placeholder="The string to encrypt"
rows="4"
multiline raw-text monospace autosize flex-1
/>
<div flex flex-1 flex-col gap-2>
<c-input-text
v-model:value="cryptPublicKey"
label="Target public key:"
placeholder="Target public key"
rows="5"
multiline raw-text monospace autosize flex-1
/>

<details>
<summary>Signing private key (optional)</summary>
<c-input-text
v-model:value="cryptPrivateKey"
label="Your private key:"
placeholder="The private key to use to sign message"
rows="5"
multiline raw-text monospace autosize flex-1
/>

<c-input-text v-model:value="cryptPrivateKeyPassphrase" label="Your private key password:" clearable raw-text />
</details>
</div>
</div>

<c-alert v-if="cryptError" type="error" mt-12 title="Error while encrypting">
{{ cryptError }}
</c-alert>

<c-input-text
label="Your text encrypted:"
:value="cryptOutput"
rows="3"
placeholder="Your string PGP message"
multiline monospace readonly autosize mt-5
/>
</c-card>

<c-card title="Decrypt">
<div flex gap-3>
<c-input-text
v-model:value="decryptInput"
label="Your PGP Message to decrypt:"
placeholder="The string to decrypt"
rows="4"
multiline raw-text monospace autosize flex-1
/>
<div flex flex-1 flex-col gap-2>
<c-input-text
v-model:value="decryptPrivateKey"
label="Your private key:"
placeholder="The private key to use to decrypt message"
rows="5"
multiline raw-text monospace autosize flex-1
/>

<c-input-text v-model:value="decryptPrivateKeyPassphrase" label="Your private key password:" clearable raw-text />

<details>
<summary>Signing public key (optional)</summary>

<c-input-text
v-model:value="decryptPublicKey"
label="Sender public key:"
placeholder="Sender public key"
rows="5"
multiline raw-text monospace autosize flex-1
/>
</details>
</div>
</div>

<c-alert v-if="decryptError" type="error" mt-12 title="Error while decrypting">
{{ decryptError }}
</c-alert>

<c-input-text
label="Your text decrypted:"
:value="decryptOutput"
rows="3"
placeholder="Your string PGP message decrypted"
multiline monospace readonly autosize mt-5
/>
</c-card>
</div>
</template>

0 comments on commit 3c8dffa

Please sign in to comment.