mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-31 14:15:14 +00:00
Improve security of SFTP server against timing attacks
Use a constant time string comparison for password auth.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
package org.kde.kdeconnect.Helpers.SecurityHelpers
|
||||
|
||||
fun constantTimeCompare(a: ByteArray, b: ByteArray): Boolean {
|
||||
if (a.size != b.size) {
|
||||
return false
|
||||
}
|
||||
var result = 0
|
||||
for (i in a.indices) {
|
||||
result = result or (a[i].toInt() xor b[i].toInt())
|
||||
}
|
||||
return result == 0
|
||||
}
|
@@ -152,7 +152,7 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
|
||||
np2.set("ip", NetworkHelper.getLocalIpAddress().getHostAddress());
|
||||
np2.set("port", server.getPort());
|
||||
np2.set("user", SimpleSftpServer.USER);
|
||||
np2.set("password", server.getPassword());
|
||||
np2.set("password", server.regeneratePassword());
|
||||
|
||||
//Kept for compatibility, in case "multiPaths" is not possible or the other end does not support it
|
||||
if (paths.size() == 1) {
|
||||
|
@@ -31,14 +31,19 @@ import org.kde.kdeconnect.Helpers.RandomHelper;
|
||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.kde.kdeconnect.Helpers.SecurityHelpers.ConstantTimeCompareKt.constantTimeCompare;
|
||||
|
||||
class SimpleSftpServer {
|
||||
private static final int STARTPORT = 1739;
|
||||
private static final int ENDPORT = 1764;
|
||||
@@ -114,7 +119,7 @@ class SimpleSftpServer {
|
||||
|
||||
public boolean start() {
|
||||
if (!started) {
|
||||
passwordAuth.password = RandomHelper.randomString(28);
|
||||
regeneratePassword();
|
||||
|
||||
port = STARTPORT;
|
||||
while (!started) {
|
||||
@@ -149,8 +154,10 @@ class SimpleSftpServer {
|
||||
return started;
|
||||
}
|
||||
|
||||
String getPassword() {
|
||||
return passwordAuth.password;
|
||||
String regeneratePassword() {
|
||||
String password = RandomHelper.randomString(28);
|
||||
passwordAuth.setPassword(password);
|
||||
return password;
|
||||
}
|
||||
|
||||
int getPort() {
|
||||
@@ -163,11 +170,25 @@ class SimpleSftpServer {
|
||||
|
||||
static class SimplePasswordAuthenticator implements PasswordAuthenticator {
|
||||
|
||||
String password;
|
||||
MessageDigest sha;
|
||||
{
|
||||
try {
|
||||
sha = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
sha.digest(password.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
byte[] passwordHash;
|
||||
|
||||
@Override
|
||||
public boolean authenticate(String user, String password, ServerSession session) {
|
||||
return user.equals(SimpleSftpServer.USER) && password.equals(this.password);
|
||||
byte[] receivedPasswordHash = sha.digest(password.getBytes(StandardCharsets.UTF_8));
|
||||
return user.equals(SimpleSftpServer.USER) && constantTimeCompare(passwordHash, receivedPasswordHash);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user