From 31fce7fdb0861816a0438b37f235b0da6cadfb63 Mon Sep 17 00:00:00 2001 From: Albert Vaca Cintora Date: Wed, 20 Sep 2023 18:38:34 +0000 Subject: [PATCH] Use Elliptic Curve encryption instead of RSA This should fix SFTP not working when using GSConnect (which doesn't specify the SSH parameters we do to allow old cyphers). Requires API 23, so on pre-23 we still use RSA. --- .../Helpers/SecurityHelpers/RsaHelper.java | 32 +++++++++++++++---- .../Helpers/SecurityHelpers/SslHelper.java | 6 +++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java index 920c873f..786c0a97 100644 --- a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/RsaHelper.java @@ -8,7 +8,9 @@ package org.kde.kdeconnect.Helpers.SecurityHelpers; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.preference.PreferenceManager; +import android.security.keystore.KeyProperties; import android.util.Base64; import android.util.Log; @@ -18,6 +20,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; @@ -29,10 +32,20 @@ public class RsaHelper { if (!settings.contains("publicKey") || !settings.contains("privateKey")) { KeyPair keyPair; + String keyAlgorithm; try { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(2048); - keyPair = keyGen.genKeyPair(); + KeyPairGenerator keyGen; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + keyAlgorithm = KeyProperties.KEY_ALGORITHM_EC; + keyGen = KeyPairGenerator.getInstance(keyAlgorithm); + ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1"); + keyGen.initialize(spec); + } else { + keyAlgorithm = "RSA"; + keyGen = KeyPairGenerator.getInstance(keyAlgorithm); + keyGen.initialize(2048); + } + keyPair = keyGen.generateKeyPair(); } catch (Exception e) { Log.e("KDE/initializeRsaKeys", "Exception", e); return; @@ -44,6 +57,7 @@ public class RsaHelper { SharedPreferences.Editor edit = settings.edit(); edit.putString("publicKey", Base64.encodeToString(publicKey, 0).trim() + "\n"); edit.putString("privateKey", Base64.encodeToString(privateKey, 0)); + edit.putString("keyAlgorithm", keyAlgorithm); edit.apply(); } @@ -53,13 +67,17 @@ public class RsaHelper { public static PublicKey getPublicKey(Context context) throws GeneralSecurityException { SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); byte[] publicKeyBytes = Base64.decode(settings.getString("publicKey", ""), 0); - return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes)); + // For backwards compat: if no keyAlgorithm setting is set, it means it was generated using RSA + String keyAlgorithm = settings.getString("keyAlgorithm", "RSA"); + return KeyFactory.getInstance(keyAlgorithm).generatePublic(new X509EncodedKeySpec(publicKeyBytes)); } public static PrivateKey getPrivateKey(Context context) throws GeneralSecurityException { - SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context); - byte[] privateKeyBytes = Base64.decode(globalSettings.getString("privateKey", ""), 0); - return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + byte[] privateKeyBytes = Base64.decode(settings.getString("privateKey", ""), 0); + // For backwards compat: if no keyAlgorithm setting is set, it means it was generated using RSA + String keyAlgorithm = settings.getString("keyAlgorithm", "RSA"); + return KeyFactory.getInstance(keyAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); } diff --git a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java index be903231..1bdf6c42 100644 --- a/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SecurityHelpers/SslHelper.java @@ -98,6 +98,8 @@ public class SslHelper { return; } + Log.i("SslHelper", "Key algorithm: " + publicKey.getAlgorithm()); + String deviceId = DeviceHelper.getDeviceId(context); boolean needsToGenerateCertificate = false; @@ -147,7 +149,9 @@ public class SslHelper { nameBuilder.build(), publicKey ); - ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey); + String keyAlgorithm = privateKey.getAlgorithm(); + String signatureAlgorithm = "RSA".equals(keyAlgorithm)? "SHA512withRSA" : "SHA512withECDSA"; + ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(privateKey); byte[] certificateBytes = certificateBuilder.build(contentSigner).getEncoded(); certificate = parseCertificate(certificateBytes);