2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-29 21:27:40 +00:00

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.
This commit is contained in:
Albert Vaca Cintora 2023-09-20 18:38:34 +00:00
parent 41f511d675
commit 31fce7fdb0
2 changed files with 30 additions and 8 deletions

View File

@ -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));
}

View File

@ -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);