diff --git a/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt b/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt index c94e558..784e125 100644 --- a/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt +++ b/src/main/kotlin/app/termora/keymgr/KeyManagerPanel.kt @@ -287,6 +287,9 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay typeComboBox.addItem("RSA") typeComboBox.addItem("ED25519") + typeComboBox.addItem("ECDSA-SHA2-NISTP256") + typeComboBox.addItem("ECDSA-SHA2-NISTP384") + typeComboBox.addItem("ECDSA-SHA2-NISTP521") // 默认 RSA lengthComboBox.addItem(1024) @@ -396,6 +399,12 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay lengthComboBox.addItem(1024 * 4) lengthComboBox.addItem(1024 * 8) lengthComboBox.selectedItem = 1024 * 2 + } else if (typeComboBox.selectedItem == "ECDSA-SHA2-NISTP256") { + lengthComboBox.addItem(256) + } else if (typeComboBox.selectedItem == "ECDSA-SHA2-NISTP384") { + lengthComboBox.addItem(384) + } else if (typeComboBox.selectedItem == "ECDSA-SHA2-NISTP521") { + lengthComboBox.addItem(521) } } } @@ -413,6 +422,17 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay super.doCancelAction() } + private fun genKeyPair(): KeyPair { + val keyType = when (typeComboBox.selectedItem) { + "ED25519" -> KeyPairProvider.SSH_ED25519 + "ECDSA-SHA2-NISTP256" -> KeyPairProvider.ECDSA_SHA2_NISTP256 + "ECDSA-SHA2-NISTP384" -> KeyPairProvider.ECDSA_SHA2_NISTP384 + "ECDSA-SHA2-NISTP521" -> KeyPairProvider.ECDSA_SHA2_NISTP521 + else -> KeyPairProvider.SSH_RSA + } + return KeyUtils.generateKeyPair(keyType, lengthComboBox.selectedItem as Int) + } + override fun doOKAction() { if (ohKeyPair == OhKeyPair.empty) { @@ -422,9 +442,7 @@ class KeyManagerPanel(private val accountOwner: AccountOwner) : JPanel(BorderLay return } - val keyType = if (typeComboBox.selectedItem == "RSA") - KeyPairProvider.SSH_RSA else KeyPairProvider.SSH_ED25519 - val keyPair = KeyUtils.generateKeyPair(keyType, lengthComboBox.selectedItem as Int) + val keyPair = genKeyPair() ohKeyPair = OhKeyPair( id = randomUUID(), name = nameTextField.text, diff --git a/src/main/kotlin/app/termora/keymgr/OhKeyPairKeyPairProvider.kt b/src/main/kotlin/app/termora/keymgr/OhKeyPairKeyPairProvider.kt index f6e67c0..3719d51 100644 --- a/src/main/kotlin/app/termora/keymgr/OhKeyPairKeyPairProvider.kt +++ b/src/main/kotlin/app/termora/keymgr/OhKeyPairKeyPairProvider.kt @@ -2,6 +2,7 @@ package app.termora.keymgr import app.termora.AES.decodeBase64 import app.termora.RSA +import org.apache.sshd.common.config.keys.impl.ECDSAPublicKeyEntryDecoder import org.apache.sshd.common.keyprovider.AbstractResourceKeyPairProvider import org.apache.sshd.common.session.SessionContext import org.apache.sshd.common.util.security.eddsa.Ed25519PublicKeyDecoder @@ -25,6 +26,8 @@ class OhKeyPairKeyPairProvider(private val id: String) : AbstractResourceKeyPair when (ohKeyPair.type) { "RSA" -> RSA.generatePublic(ohKeyPair.publicKey.decodeBase64()) "ED25519" -> Ed25519PublicKeyDecoder.INSTANCE.generatePublicKey((X509EncodedKeySpec(ohKeyPair.publicKey.decodeBase64()))) + "ECDSA-SHA2-NISTP256","ECDSA-SHA2-NISTP384","ECDSA-SHA2-NISTP521" -> + ECDSAPublicKeyEntryDecoder.INSTANCE.generatePublicKey(X509EncodedKeySpec(ohKeyPair.publicKey.decodeBase64())) else -> throw UnsupportedOperationException("${ohKeyPair.type} is not supported") } } as PublicKey @@ -33,6 +36,8 @@ class OhKeyPairKeyPairProvider(private val id: String) : AbstractResourceKeyPair when (ohKeyPair.type) { "RSA" -> RSA.generatePrivate(ohKeyPair.privateKey.decodeBase64()) "ED25519" -> Ed25519PublicKeyDecoder.INSTANCE.generatePrivateKey(PKCS8EncodedKeySpec(ohKeyPair.privateKey.decodeBase64())) + "ECDSA-SHA2-NISTP256","ECDSA-SHA2-NISTP384","ECDSA-SHA2-NISTP521" -> + ECDSAPublicKeyEntryDecoder.INSTANCE.generatePrivateKey(PKCS8EncodedKeySpec(ohKeyPair.privateKey.decodeBase64())) else -> throw UnsupportedOperationException("${ohKeyPair.type} is not supported") } } as PrivateKey diff --git a/src/test/kotlin/app/termora/KeyUtilsTest.kt b/src/test/kotlin/app/termora/KeyUtilsTest.kt index 6e93f38..b4188fe 100644 --- a/src/test/kotlin/app/termora/KeyUtilsTest.kt +++ b/src/test/kotlin/app/termora/KeyUtilsTest.kt @@ -15,6 +15,19 @@ class KeyUtilsTest { assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair("ssh-rsa", 1024).public), 1024) } + + @Test + fun test_ECDSA() { + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP256, 256).private), 256) + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP256, 256).public), 256) + + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP384, 384).private), 384) + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP384, 384).public), 384) + + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP521, 521).private), 521) + assertEquals(KeyUtils.getKeySize(KeyUtils.generateKeyPair(KeyPairProvider.ECDSA_SHA2_NISTP521, 521).public), 521) + } + @Test fun test_ed25519() { val keyPair = KeyUtils.generateKeyPair(KeyPairProvider.SSH_ED25519, 256) diff --git a/src/test/resources/sshd/Dockerfile b/src/test/resources/sshd/Dockerfile index 23b16c2..f8adff7 100644 --- a/src/test/resources/sshd/Dockerfile +++ b/src/test/resources/sshd/Dockerfile @@ -1,4 +1,4 @@ -FROM linuxserver/openssh-server +FROM linuxserver/openssh-server:9.3_p2-r1-ls147 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ && apk update && apk add wget tmux gcc zip p7zip g++ git make zsh htop stress-ng inetutils-telnet xclock xcalc xorg-server xinit && wget https://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz \ && tar -xf lrzsz-0.12.20.tar.gz && cd lrzsz-0.12.20 && ./configure && make && make install \