Skip to content

Commit 365fb4b

Browse files
committed
Merge branch 'feat/ed25519-keygen' into chore/all-my-stuffs
# Conflicts: # components.d.ts # package.json # pnpm-lock.yaml # src/tools/index.ts
2 parents 8617af9 + ca44c5c commit 365fb4b

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import sshpk from 'sshpk';
2+
3+
export { generateKeyPair };
4+
5+
async function generateKeyPair(config: {
6+
password?: string
7+
format?: sshpk.PrivateKeyFormatType
8+
comment?: string
9+
} = {}) {
10+
const privKey = sshpk.generatePrivateKey('ed25519');
11+
privKey.comment = config?.comment;
12+
13+
const pubFormat = config.format ?? 'ssh';
14+
let privFormat: sshpk.PrivateKeyFormatType = config.format ?? 'ssh';
15+
if (privFormat === 'ssh') {
16+
privFormat = 'ssh-private';
17+
}
18+
const pubKey = privKey.toPublic();
19+
return {
20+
publicKey: pubKey.toString(pubFormat),
21+
privateKey: config?.password
22+
? privKey.toString(privFormat,
23+
{
24+
passphrase: config?.password,
25+
comment: config?.comment,
26+
},
27+
)
28+
: privKey.toString(privFormat, { comment: config?.comment }),
29+
};
30+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<script setup lang="ts">
2+
import type sshpk from 'sshpk';
3+
import { generateKeyPair } from './ed25519-key-pair-generator.service';
4+
import TextareaCopyable from '@/components/TextareaCopyable.vue';
5+
import { withDefaultOnErrorAsync } from '@/utils/defaults';
6+
import { computedRefreshableAsync } from '@/composable/computedRefreshable';
7+
8+
const password = ref('');
9+
const comment = ref('');
10+
const emptyCerts = { publicKey: '', privateKey: '' };
11+
12+
const format = useStorage('ed25519-key-pair-generator:format', 'ssh');
13+
const formatOptions = [
14+
{ value: 'pem', label: 'PEM' },
15+
{ value: 'pkcs8', label: 'PKCS#8' },
16+
{ value: 'ssh', label: 'OpenSSH Standard' },
17+
{ value: 'openssh', label: 'OpenSSH New' },
18+
{ value: 'putty', label: 'PuTTY' },
19+
];
20+
21+
const supportsPassphrase = computed(() => format.value === 'ssh');
22+
23+
const [certs, refreshCerts] = computedRefreshableAsync(
24+
() => withDefaultOnErrorAsync(() => generateKeyPair(
25+
{
26+
password: password.value,
27+
format: format.value as sshpk.PrivateKeyFormatType,
28+
comment: comment.value,
29+
},
30+
), emptyCerts),
31+
emptyCerts,
32+
);
33+
</script>
34+
35+
<template>
36+
<div>
37+
<n-space mb-2>
38+
<c-select
39+
v-model:value="format"
40+
label-position="left"
41+
label="Format:"
42+
:options="formatOptions"
43+
placeholder="Select a key format"
44+
/>
45+
46+
<n-form-item v-if="supportsPassphrase" label="Passphrase :" label-placement="left">
47+
<n-input
48+
v-model:value="password"
49+
type="password"
50+
show-password-on="mousedown"
51+
placeholder="Passphrase"
52+
/>
53+
</n-form-item>
54+
</n-space>
55+
56+
<n-space mb-2>
57+
<n-form-item label="Comment :" label-placement="left">
58+
<n-input
59+
v-model:value="comment"
60+
type="text"
61+
placeholder="Comment"
62+
/>
63+
</n-form-item>
64+
65+
<c-button @click="refreshCerts">
66+
Refresh key-pair
67+
</c-button>
68+
</n-space>
69+
70+
<div>
71+
<h3>Public key</h3>
72+
<TextareaCopyable :value="certs.publicKey" :word-wrap="true" />
73+
</div>
74+
75+
<div>
76+
<h3>Private key</h3>
77+
<TextareaCopyable :value="certs.privateKey" />
78+
</div>
79+
</div>
80+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Certificate } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'Ed25519 key pair generator',
6+
path: '/ed25519-key-pair-generator',
7+
description: 'Generate new random Ed25519 private and public keys (with or without passphrase).',
8+
keywords: ['ed25519', 'key', 'pair', 'generator', 'public', 'private', 'secret', 'ssh', 'pem', 'passphrase', 'password'],
9+
component: () => import('./ed25519-key-pair-generator.vue'),
10+
icon: Certificate,
11+
createdAt: new Date('2024-02-14'),
12+
});

src/tools/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import { tool as csrGenerator } from './csr-generator';
110110
import { tool as dockerRunToKubernetesConverter } from './docker-run-to-kubernetes';
111111
import { tool as dockerComposeValidator } from './docker-compose-validator';
112112
import { tool as ecdsaKeyPairGenerator } from './ecdsa-key-pair-generator';
113+
import { tool as ed25519KeyPairGenerator } from './ed25519-key-pair-generator';
113114
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
114115
import { tool as numeronymGenerator } from './numeronym-generator';
115116
import { tool as macAddressGenerator } from './mac-address-generator';
@@ -244,6 +245,9 @@ export const toolsByCategory: ToolCategory[] = [
244245
passwordStrengthAnalyser,
245246
pdfSignatureChecker,
246247
ecdsaKeyPairGenerator,
248+
ed25519KeyPairGenerator,
249+
passwordStrengthAnalyser,
250+
pdfSignatureChecker,
247251
],
248252
},
249253
{

0 commit comments

Comments
 (0)