Aprende a leer y escribir credenciales en archivos de KeePass.

Cómo manipular las bases de datos de KeePass (archivos kdbx) en Java

KeePass es un administrador de contraseñas de código abierto gratuito, que le ayuda a administrar sus contraseñas de forma segura. Puede poner todas sus contraseñas en una base de datos, que está bloqueada con una clave maestra o un archivo de claves. Características de esta aplicación:

  • KeePass admite el Estándar de cifrado avanzado (AES, Rijndael) y el algoritmo Twofish para cifrar sus bases de datos de contraseñas. Ambos cifrados se consideran muy seguros. AES, por ejemplo, se convirtió en un estándar del gobierno federal de los EE. UU. Y está aprobado por la Agencia de Seguridad Nacional (NSA) para obtener información de alto secreto.
  • La base de datos completa está encriptada, no solo los campos de contraseña. Por lo tanto, sus nombres de usuario, notas, etc. también están encriptados.
  • SHA-256 se utiliza para codificar los componentes de la clave maestra. SHA-256 es una función hash unidireccional criptográficamente segura de 256 bits. Aún no se conocen ataques contra SHA-256. La salida se transforma mediante una función de derivación de claves.
  • Protección contra ataques de diccionario y adivinanzas: al transformar el hash del componente de clave maestra mediante una función de derivación de claves (AES-KDF, Argon2, ...), los ataques de diccionario y adivinanzas pueden hacerse más difíciles.
  • Protección de la memoria del proceso: sus contraseñas se cifran mientras KeePass se está ejecutando, por lo que incluso cuando el sistema operativo descarga el proceso de KeePass en el disco, sus contraseñas no se revelan.
  • [2.x] Flujos en memoria protegidos: al cargar el formato XML interno, las contraseñas se cifran mediante una clave de sesión.
  • Controles de edición de contraseña con seguridad mejorada: KeePass es el primer administrador de contraseñas que cuenta con controles de edición de contraseña con seguridad mejorada. Ninguno de los espías de control de edición de contraseñas disponibles funciona contra estos controles. Las contraseñas ingresadas en esos controles ni siquiera son visibles en la memoria de proceso de KeePass.
  • El cuadro de diálogo de la clave maestra se puede mostrar en un escritorio seguro, en el que casi no funciona ningún keylogger. Auto-Type también puede protegerse contra keyloggers.

Como la aplicación utiliza una lógica pública, existen bibliotecas para manipular este tipo de archivos con diferentes lenguajes de programación, y Java no es la excepción. En este artículo, le explicaremos cómo manipular las bases de datos KeePass con Java, ya sea para crear su propia aplicación similar o simplemente para extraer la información de los archivos kdbx.

1. Instale la biblioteca Open KeePass

Para manipular las bases de datos de KeePass, deberá instalar la biblioteca openkeepass. openkeepass es una biblioteca java para leer y escribir bases de datos KeePass. Se trata de una biblioteca de Java intuitiva que soporta KeePass archivos de bases de datos 2.x . La biblioteca ofrece soporte hasta ahora para: 

  • Soporte de lectura y escritura para KeePass 2.x
  • Credenciales de contraseña o archivo de claves: openkeepass puede abrir bases de datos protegidas por contraseña así como bases de datos protegidas por archivos de claves.
  • Compatibilidad con Android: se ejecutará en dispositivos Android.
  • API fácil de aprender: openkeepass tiene una API simple con métodos convenientes que facilitan la lectura de datos de una base de datos KeePass.
  • Muy delgado: openkeepass intenta mantener las dependencias necesarias al mínimo absoluto.
  • Compatible con versiones anteriores hasta Java 6

Puedes descargar el archivo jar del paquete desde el repositorio de maven  e incluirlo manualmente en su proyecto o si su proyecto está basado en maven, puede editar el pom.xmlarchivo y agregar la dependencia:

<!-- https://mvnrepository.com/artifact/de.slackspace/openkeepass -->
<dependency>
    <groupId>de.slackspace</groupId>
        <artifactId>openkeepass</artifactId>
    <version>0.8.1</version>
</dependency>

Para obtener más información sobre este proyecto, visita el repositorio oficial en Github aquí.

2. Extracción de información

Como todo en Our Code World, aprenderás con la práctica, por lo que te explicaremos cómo manejar las necesidades más básicas cuando intente trabajar con estos archivos:

Imprimir todas las credenciales

Si acaba de obtener una base de datos KeePass de alguien y solo necesita obtener la información sin preocuparse por la categorización, puede imprimir fácilmente todas las credenciales almacenadas en el archivo con la siguiente lógica:

package com.ourcodeworld.mavensandbox;

// Importar clase requerida
import de.slackspace.openkeepass.KeePassDatabase;
import de.slackspace.openkeepass.domain.Entry;
import de.slackspace.openkeepass.domain.KeePassFile;
import java.util.List;

public class Index {
    
    public static void main(String[] args){
        
        // 1. Abra un archivo de base de datos KeePass a través de una contraseña de texto sin formato
        KeePassFile database = KeePassDatabase
            .getInstance("C:\\Users\\sdkca\\Documents\\Database.kdbx")
            .openDatabase("12345");
		
        // 2. Recuperar todas las entradas
        List<Entry> entries = database.getEntries();
            
        // 3. Imprime cada entrada
        for (Entry entry : entries) {
            System.out.println("    * Credential: " + entry.getTitle());
                System.out.println("        Username: " + entry.getUsername());
                System.out.println("        Password: " + entry.getPassword());
        }
    }
}

Esta lógica generará la siguiente salida en el terminal:

* Credential: Sample Entry
    Username: User Name
    Password: Password
* Credential: Sample Entry #2
    Username: Michael321
    Password: 12345
* Credential: Windows User
    Username: cheese@outlook.com
    Password: 123456
* Credential: Wi-Fi
    Username: bathouse
    Password: 654321
* Credential: Contact Email
    Username: dev@ourcodeworld.com
    Password: 123456
* Credential: Info Email
    Username: info@ourcodeworld.com
    Password: 123456789
* Credential: Bank Of America
    Username: ourcodeworld
    Password: 123456

Imprimir información de forma estructurada (por grupos)

Como usuario habitual de la aplicación Keepass, me encanta clasificar las credenciales que almaceno en mi archivo usando grupos y subgrupos. Por ejemplo, separando las credenciales de mi vida personal con cuentas relacionadas con el trabajo:

KeePass Categories or Groups

Puedes extraer la información de esta manera además de iterar primero por grupos y luego obtener las entradas dentro del grupo:

package com.ourcodeworld.mavensandbox;

// Importar clase requerida
import de.slackspace.openkeepass.KeePassDatabase;
import de.slackspace.openkeepass.domain.Entry;
import de.slackspace.openkeepass.domain.Group;
import de.slackspace.openkeepass.domain.KeePassFile;
import java.util.List;

public class Index {
    
    public static void main(String[] args){
        
        // 1. Abra un archivo de base de datos KeePass a través de una contraseña de texto sin formato
        KeePassFile database = KeePassDatabase
            .getInstance("C:\\Users\\sdkca\\Documents\\Database.kdbx")
            .openDatabase("12345");
		 
        // 2. Obtenga los mejores grupos de la base de datos
        List<Group> keePassGroups = database.getTopGroups();
            
        // 3. Iterar sobre el tema
        for (Group group : keePassGroups) {

            // 4. Imprime el nombre del grupo
            System.out.println(" - " + group.getName());

            // 5. Lista de credenciales dentro de este grupo
            List<Entry> groupEntries = group.getEntries();
            
            // 6. Imprime todas las credenciales dentro del grupo
            for (Entry entry : groupEntries) {
                System.out.println("    * Credencial: " + entry.getTitle());
                System.out.println("        Username: " + entry.getUsername());
                System.out.println("        Password: " + entry.getPassword());
            }
        }
    }
}

Este código generará la siguiente salida en la terminal:

 - Windows
    * Credential: Windows User
        Username: cheese@outlook.com
        Password: 123456
 - Network
    * Credential: Wi-Fi
        Username: bathouse
        Password: 654321
 - eMail
    * Credential: Contact Email
        Username: dev@ourcodeworld.com
        Password: 123456
    * Credential: Info Email
        Username: info@ourcodeworld.com
        Password: 123456789
 - Homebanking
    * Credential: Bank Of America
        Username: ourcodeworld
        Password: 123456
 - Recycle Bin

Obtención de una credencial única por su título

Como no hay indexación a través de ID o algo numérico, la única forma de obtener una sola credencial de la base de datos es a través de su título, por ejemplo:

package com.ourcodeworld.mavensandbox;

// Importar clase requerida
import de.slackspace.openkeepass.KeePassDatabase;
import de.slackspace.openkeepass.domain.Entry;
import de.slackspace.openkeepass.domain.KeePassFile;
import java.util.List;

public class Index {
    
    public static void main(String[] args){
        
        // 1. Abra un archivo de base de datos KeePass a través de una contraseña de texto sin formato
        KeePassFile database = KeePassDatabase
            .getInstance("C:\\Users\\sdkca\\Documents\\Database.kdbx")
            .openDatabase("12345");
	
        // 2. Encuentre una sola credencial por título
        Entry sampleEntry = database.getEntryByTitle("Sample Entry");
	    System.out.println("Title: " + sampleEntry.getTitle() + " Password: " + sampleEntry.getPassword());
    }
}

Esto se imprimirá en la terminal:

Title: Sample Entry Password: Password

Sin embargo, ¿qué sucede si tiene más de una credencial que tiene el mismo nombre o contiene la misma cadena? Luego, deberá obtener las entradas que contienen el texto específico e iterar sobre el resultado para saber qué credencial coincide con la búsqueda:

package com.ourcodeworld.mavensandbox;

// Importar clase requerida
import de.slackspace.openkeepass.KeePassDatabase;
import de.slackspace.openkeepass.domain.Entry;
import de.slackspace.openkeepass.domain.KeePassFile;
import java.util.List;

public class Index {
    
    public static void main(String[] args){
        
        // 1. Abra un archivo de base de datos KeePass a través de una contraseña de texto sin formato
        KeePassFile database = KeePassDatabase
            .getInstance("C:\\Users\\sdkca\\Documents\\Database.kdbx")
            .openDatabase("12345");
	
        // 2. Busque todas las entradas que contengan 'Muestra' en el título
        List<Entry> entriesByTitle = database.getEntriesByTitle("Sample", false);
        for (Entry entry : entriesByTitle) {
                System.out.println("Title: " + entry.getTitle() + " Password: " + entry.getPassword());
        }
    }
}

Esto se imprimirá en su lugar:

Title: Sample Entry Password: Password
Title: Sample Entry #2 Password: 12345

Que te diviertas ❤️!


Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores