From 503cf6715c01992c5d7a0121908806d1437fecfe Mon Sep 17 00:00:00 2001 From: sharevb Date: Sat, 17 Feb 2024 17:28:58 +0100 Subject: [PATCH] feat(rsa-key-generator): passphrase and formats Fix #281 (rsa with passphrase and comment) Supports many formats: PEM (with or without passphrase), PKCS#1, PKCS#8, OpenSSH Standard (with or without passphrase), OpenSSH (new format) and PuTTY --- components.d.ts | 2 + package.json | 6 +- src/tools/rsa-key-pair-generator/index.ts | 4 +- .../rsa-key-pair-generator.service.ts | 35 +++++++- .../rsa-key-pair-generator.vue | 81 +++++++++++++++---- 5 files changed, 105 insertions(+), 23 deletions(-) diff --git a/components.d.ts b/components.d.ts index fabbe793..18828739 100644 --- a/components.d.ts +++ b/components.d.ts @@ -156,6 +156,7 @@ declare module '@vue/runtime-core' { NH3: typeof import('naive-ui')['NH3'] NIcon: typeof import('naive-ui')['NIcon'] NImage: typeof import('naive-ui')['NImage'] + NInput: typeof import('naive-ui')['NInput'] NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel'] NInputNumber: typeof import('naive-ui')['NInputNumber'] @@ -165,6 +166,7 @@ declare module '@vue/runtime-core' { NProgress: typeof import('naive-ui')['NProgress'] NScrollbar: typeof import('naive-ui')['NScrollbar'] NSlider: typeof import('naive-ui')['NSlider'] + NSpace: typeof import('naive-ui')['NSpace'] NStatistic: typeof import('naive-ui')['NStatistic'] NSwitch: typeof import('naive-ui')['NSwitch'] NTable: typeof import('naive-ui')['NTable'] diff --git a/package.json b/package.json index be4267c4..7c1bd24a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "it-tools", - "version": "2023.11.2-7d94e11", + "version": "2023.12.21-5ed3693", "description": "Collection of handy online tools for developers, with great UX. ", "keywords": [ "productivity", @@ -86,7 +86,7 @@ "unplugin-auto-import": "^0.16.4", "uuid": "^9.0.0", "vue": "^3.3.4", - "vue-i18n": "^9.2.2", + "vue-i18n": "^9.9.1", "vue-router": "^4.1.6", "vue-tsc": "^1.8.1", "xml-formatter": "^3.3.2", @@ -95,7 +95,7 @@ "devDependencies": { "@antfu/eslint-config": "^0.41.0", "@iconify-json/mdi": "^1.1.50", - "@intlify/unplugin-vue-i18n": "^0.13.0", + "@intlify/unplugin-vue-i18n": "^2.0.0", "@playwright/test": "^1.32.3", "@rushstack/eslint-patch": "^1.2.0", "@tsconfig/node18": "^18.2.0", diff --git a/src/tools/rsa-key-pair-generator/index.ts b/src/tools/rsa-key-pair-generator/index.ts index 3d034e5b..4c844707 100644 --- a/src/tools/rsa-key-pair-generator/index.ts +++ b/src/tools/rsa-key-pair-generator/index.ts @@ -5,8 +5,8 @@ import { translate } from '@/plugins/i18n.plugin'; export const tool = defineTool({ name: translate('tools.rsa-key-pair-generator.title'), path: '/rsa-key-pair-generator', - description: translate('tools.rsa-key-pair-generator.description'), - keywords: ['rsa', 'key', 'pair', 'generator', 'public', 'private', 'secret', 'ssh', 'pem'], + description: 'Generate new random RSA private and public keys (with or without passphrase).', + keywords: ['rsa', 'key', 'pair', 'generator', 'public', 'private', 'secret', 'ssh', 'pem', 'passphrase', 'password'], component: () => import('./rsa-key-pair-generator.vue'), icon: Certificate, }); diff --git a/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.service.ts b/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.service.ts index 1cb1f1ae..34b06f26 100644 --- a/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.service.ts +++ b/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.service.ts @@ -1,5 +1,6 @@ import { pki } from 'node-forge'; import workerScript from 'node-forge/dist/prime.worker.min?url'; +import sshpk from 'sshpk'; export { generateKeyPair }; @@ -16,11 +17,39 @@ function generateRawPairs({ bits = 2048 }) { ); } -async function generateKeyPair(config: { bits?: number } = {}) { +async function generateKeyPair(config: { + bits?: number + password?: string + format?: sshpk.PrivateKeyFormatType + comment?: string +} = {}) { const { privateKey, publicKey } = await generateRawPairs(config); + const privateUnencryptedKeyPem = pki.privateKeyToPem(privateKey); + + if (config?.format === 'pem') { + return { + publicKey: pki.publicKeyToPem(publicKey), + privateKey: config?.password + ? pki.encryptRsaPrivateKey(privateKey, config?.password) + : privateUnencryptedKeyPem, + }; + } + + const privKey = sshpk.parsePrivateKey(privateUnencryptedKeyPem); + privKey.comment = config?.comment; + const pubFormat = config.format ?? 'ssh'; + let privFormat = config.format ?? 'ssh'; + if (privFormat === 'ssh') { + privFormat = 'ssh-private'; + } + const pubKey = privKey.toPublic(); return { - publicKeyPem: pki.publicKeyToPem(publicKey), - privateKeyPem: pki.privateKeyToPem(privateKey), + publicKey: pubKey.toString(pubFormat), + privateKey: config?.password + ? privKey.toString(privFormat, + { passphrase: config?.password, comment: config?.comment }, + ) + : privKey.toString(privFormat, { comment: config?.comment }), }; } diff --git a/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue b/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue index 7f972464..3ca9f7bd 100644 --- a/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue +++ b/src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue @@ -1,4 +1,5 @@