Fork me on GitHub

Programming, Internet & more

Openkeepass: Java API for KeePass 2.x

KeePass is a well known password safe for your passwords. It has a lot of features, proved security and is really a good way of storing your passwords and login information. Personally, I’m using KeePass for a long time now.

Java API for KeePass

However, sometimes there is a need that you have to access the KeePass database programmatically. And there comes the problem. There are really good frameworks available for C# but if you’ve ever looked for an opensource java library that is capable of reading KeePass 2.x databases you were probably surprised that there are only libraries out there that can read KeePass 1.x databases.

I guess this has to do with the fact that the file format of KeePass 2.x has dramatically changed since the old 1.x version and is now based on XML. However, since there is no alternative available I’ve managed to write my own java API for KeePass 2.x files.

Openkeepass for reading KeePass files

With the library you will get a quick way to access the database files. I’ve tried to make the API as simple as possible to use.
If you want to read all password entries from a KeePass database you can achieve that with the following code:

// Open Database
KeePassFile database = KeePassDatabase.getInstance("Database.kdbx").openDatabase("MasterPassword");

// Retrieve all entries
List<Entry> entries = database.getEntries();

If you want to search for a specific entry you can do that as well:

// Search for single entry
Entry sampleEntry = database.getEntryByTitle("Sample Entry");

Looking for entries that contain a specific string? No problem:

// Search for entries that contain the word 'entry'
List<Entry> entries = keePassFile.getEntriesByTitle("entry", false);

You could also work with groups:

// Retrieve all groups of the first level
List<Group> groups = keePassFile.getTopGroups();

There are more examples available on GitHub.

Installation

If you want to use openkeepass, you can grab it directly from GitHub or even simpler just add it as a maven dependency.

<dependency>
    <groupId>de.slackspace</groupId>
    <artifactId>openkeepass</artifactId>
    <version>0.4.0</version>
</dependency>

Pitfalls

There is one pitfall that you could fall into while using the library. While KeePass is using strong cryptography, you have to make sure that you’ve installed the Java Cryptography Extension (JCE) on your system. You can download it directly from Oracle.

If you have not installed it, you will run into an InvalidKeyException:

java.security.InvalidKeyException: Illegal key size

OpenSource

As always the whole source code is opensource and available on GitHub.

Category: open-source

12 Comments

  • Bengt Månsson says:

    org.bouncycastle.util.encoders.DecoderException: unable to decode base64 data: -4
    at org.bouncycastle.util.encoders.Base64.decode(Base64.java:112)
    at de.slackspace.openkeepass.crypto.Salsa20.decrypt(Salsa20.java:41)
    at de.slackspace.openkeepass.parser.KeePassDatabaseXmlParser.decryptAndSetValues(KeePassDatabaseXmlParser.java:42)
    at de.slackspace.openkeepass.parser.KeePassDatabaseXmlParser.parse(KeePassDatabaseXmlParser.java:24)
    at de.slackspace.openkeepass.KeePassDatabase.decryptAndParseDatabase(KeePassDatabase.java:291)
    at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:208)

    Every time I try an entry with a blank password

  • Ron says:

    Nice work, are you thinking of adding the option to write to the keepass database?

  • hassai says:

    Hello,

    thank you for this article
    i need to write entrees to keepass database,
    do you know any API that can help me please ?

    regards

    HASSAI

  • Mika says:

    Hello

    I’m trying to open a password protected DB following the example provided on GitHub but I keep getting below exception on the openDatabase instruction.

    Exception in thread “main” java.lang.RuntimeException: Could not move right because the last node at this level has already been reached
    at de.slackspace.openkeepass.domain.zipper.GroupZipper.right(GroupZipper.java:140)
    at de.slackspace.openkeepass.domain.zipper.GroupZipper$GroupIterator.getNextRightNode(GroupZipper.java:287)
    at de.slackspace.openkeepass.domain.zipper.GroupZipper$GroupIterator.getNextRightNode(GroupZipper.java:289)
    at de.slackspace.openkeepass.domain.zipper.GroupZipper$GroupIterator.getNextRightNode(GroupZipper.java:289)
    at de.slackspace.openkeepass.domain.zipper.GroupZipper$GroupIterator.next(GroupZipper.java:321)
    at de.slackspace.openkeepass.domain.zipper.GroupZipper$GroupIterator.next(GroupZipper.java:1)
    at de.slackspace.openkeepass.domain.enricher.IconEnricher.enrichNodesWithIconData(IconEnricher.java:45)
    at de.slackspace.openkeepass.xml.KeePassDatabaseXmlParser.fromXml(KeePassDatabaseXmlParser.java:25)
    at de.slackspace.openkeepass.KeePassDatabase.decryptAndParseDatabase(KeePassDatabase.java:317)
    at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:172)

    Any hint?

    Thanks,
    Mika

    • Christian says:

      Hey Mika,

      Could you create an issue on GitHub for this? I guess there must be something special in your KeePass database. It would be ideal if you could provide the KeePass database also (of course with obfuscated passwords/usernames etc.).

  • Mika says:

    Hello

    Is it possible to access attributes like creation time / last modification time?

    Thanks,
    Mika

  • hassai says:

    How can we add entry to existing group without overwriting existing entries PLZ ?

  • Vikram says:

    I used this API to read expiry information as well as add new groups to existing Keepass database file.

    KeePassFile database = KeePassDatabase.getInstance(kpsDatabaseFile).openDatabase(kpsDatabasePasswd);

    // Retrieve all entries
    List entries = database.getEntries();
    for (Entry entry : entries) {
    System.out.println(“Title: ” + entry.getTitle() + ” Password: ” + entry.getPassword() + ” Expiry: ”
    + SimpleDateFormat.getDateInstance().format(entry.getTimes().getExpiryTime().getTime()));
    }

    // Retrieve all top groups
    List groups = database.getTopGroups();

    for (Group group : groups) {

    System.out.println(group.getName());
    }

    Group groupWrite = new GroupBuilder(“Test Group”).build();
    groups.add(groupWrite);

    KeePassFile keePassFile = new KeePassFileBuilder(database).build();
    KeePassDatabase.write(keePassFile, kpsDatabasePasswd, kpsDatabaseFile);

Leave a Reply

Your email address will not be published. Required fields are marked *