cternes / openkeepass Goto Github PK
View Code? Open in Web Editor NEW[Deprecated] A java library for reading and writing KeePass databases. It is an intuitive java library that supports KeePass 2.x database files.
License: Apache License 2.0
[Deprecated] A java library for reading and writing KeePass databases. It is an intuitive java library that supports KeePass 2.x database files.
License: Apache License 2.0
The maximum number of items of management of history is Is the responsibility of the outside of the database library?
@Test
public void testBuildWithHistory2() throws FileNotFoundException {
//Create DB
{
final KeePassFile keePassFile = new KeePassFileBuilder("testDB").build();
FileOutputStream out = null;
//Default 10
Assert.assertEquals(10, keePassFile.getMeta().getHistoryMaxItems());
try {
out = new FileOutputStream("test/xxx.kdbx");
KeePassDatabase.write(keePassFile, "test", out);
} finally {
IOUtils.closeQuietly(out);
}
}
//Open / Add Entry / Write
{
File fileX = new File("test/xxx.kdbx");
File fileY = new File("test/yyy.kdbx");
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(fileX);
out = new FileOutputStream(fileY);
final KeePassFile keePassFile = KeePassDatabase.getInstance(fileX).openDatabase("test");
UUID uuid = UUID.randomUUID();
Entry entry1 = new EntryBuilder("v1").uuid(uuid).build();
Entry entry2 = new EntryBuilder(entry1).title("v2").buildWithHistory();
Entry entry3 = new EntryBuilder(entry2).title("v3").buildWithHistory();
Entry entry4 = new EntryBuilder(entry3).title("v4").buildWithHistory();
Entry entry5 = new EntryBuilder(entry4).title("v5").buildWithHistory();
Entry entry6 = new EntryBuilder(entry5).title("v6").buildWithHistory();
Entry entry7 = new EntryBuilder(entry6).title("v7").buildWithHistory();
Entry entry8 = new EntryBuilder(entry7).title("v8").buildWithHistory();
Entry entry9 = new EntryBuilder(entry8).title("v9").buildWithHistory();
Entry entry10 = new EntryBuilder(entry9).title("v10").buildWithHistory();
Entry entry11 = new EntryBuilder(entry10).title("v11").buildWithHistory();
Entry entry12 = new EntryBuilder(entry11).title("v12").buildWithHistory();
new GroupBuilder(keePassFile.getRoot().getGroups().get(0)).addEntry(entry12).build();
KeePassDatabase.write(keePassFile, "test", out);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
}
//History Size Check
{
File fileY = new File("test/yyy.kdbx");
FileInputStream in = null;
try {
in = new FileInputStream(fileY);
final KeePassFile keePassFile = KeePassDatabase.getInstance(fileY).openDatabase("test");
Entry entry = keePassFile.getRoot().getGroups().get(0).getEntries().get(0);
Assert.assertEquals(10, entry.getHistory().getHistoricEntries().size());
} finally {
IOUtils.closeQuietly(in);
}
}
}
Compatibility of Java6 Do you need?
Java6
try {
return hash (text.getBytes ( "UTF-8"));
} Catch (UnsupportedEncodingException e) {
throw new UnsupportedOperationException ( "The encoding 'UTF-8' is not supported", e);
}
Java7+
return hash (text.getBytes (StandardCharsets.UTF_8));`
%i -> %d
throw new IllegalArgumentException(String.format("Value %i is not a valid CrsAlgorithm", value));
public enum CrsAlgorithm {
Null, ArcFourVariant, Salsa20;
public static CrsAlgorithm parseValue(int value) {
switch (value) {
case 0:
return Null;
case 1:
return ArcFourVariant;
case 2:
return Salsa20;
default:
throw new IllegalArgumentException(String.format("Value %i is not a valid CrsAlgorithm", value));
}
}
This behavior There are two problems.
Test Code
@Test
public void testKeePass() throws IOException{
//Create DB
{
final KeePassFile keePassFile = new KeePassFileBuilder("testDB").build();
final FileOutputStream out = new FileOutputStream("xxx.kdbx");
try {
KeePassDatabase.write(keePassFile, "test", out);
} finally {
IOUtils.closeQuietly(out);
}
}
//Open / Add Entry / Write / Assert
{
File fileX = new File("xxx.kdbx");
File fileY = new File("yyy.kdbx");
final FileInputStream in = new FileInputStream(fileX);
final FileOutputStream out = new FileOutputStream(fileY);
try {
final KeePassFile keePassFile = KeePassDatabase.getInstance(fileX).openDatabase("test");
UUID uuid = UUID.randomUUID();
Entry enrty = new EntryBuilder(uuid).title("title").password("password").build();
new GroupBuilder(keePassFile.getRoot().getGroups().get(0)).addEntry(enrty).build();
KeePassDatabase.write(keePassFile, "test", out);
// Password Wrong?
Assert.assertEquals("password", enrty.getPassword());
Assert.assertEquals("password", keePassFile.getRoot().getGroups().get(0).getEntries().get(0).getPassword());
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
}
}
The EntryBuilder class should have times (Times) method?
The GroupBuilder class there are times (Times) method.
Dear @cternes,
According to https://keepass.info/help/base/security.html the "ChaCha20 is the successor of the Salsa20 algorithm" and KeePass 2.x supports it.
According to the source, openkeepass supports KeePass 2.x and Salsa20 algorithm.
Proposal of the User Story description:
As an openkeepass user, I would like to use KeePass 2.x database files with the following configurations:
Proposal unit tests for the User Story:
ha3ext@4e199d1
I am looking forward to your reply.
Thank you!
Sincerely,
Attila Horvath
Software Engineer
Digitalization
We are using KeePass for tracking service account credentials per application in our environment. It is possible, we will have the same user/pass for multiple applications--but our system requires a unique KeePass entry. As a result, we've tried out adding new entries that have the Username and Password fields referenence an existing/master entry. In the KeePass UI, you'll see the value for the stored Username (or Password or whatever field you're adding reference too) is something in the form of {REF:U@I:36F89B594FD7664E89E62E8CE220129A}. Once we started doing that, our automation broke (that is using the OpenKeePass library) because the usernames & passwords returned weren't the linked values but the links themselves, ie: {REF:U@I:36F89B594FD7664E89E62E8CE220129A}.
I've done my best to dig into the code and don't see any support for this concept. Is it possible to add the ability to resolve the value if an Entry has a linked reference?
Example:
Title: Item 1, Username: masterUser, UUID 36F89B594FD7664E89E62E8CE220129A
Title: Item 2, Username: {REF:U@I:36F89B594FD7664E89E62E8CE220129A}
When doing database.getEntryByTitle("Item 2").getUsername();
it would be nice to have masterUser returned.
Thanks!
I'd like to be able to read / write entry attachments from a KeePass database (I often attach long keys and certificates this way), but am unable to find any calls that point at this functionality.
Thanks!
Thanks for providing this library.
I am using java 9 and get this warning.
"C:\Program Files\Java\jdk-9.0.1\bin\java" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.2.5\lib\idea_rt.jar=36002:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2017.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\Dev\Fox\out\production\classes;C:\Dev\Fox\out\production\resources;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-slf4j-impl\2.5\d1e34a4525e08873703fdaad6c6284f944f8ca8f\log4j-slf4j-impl-2.5.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.slf4j\jcl-over-slf4j\1.7.19\44a8aec96a518fc7728a6b1d2fa5aa83b944d586\jcl-over-slf4j-1.7.19.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.19\3bf03cd91f15d55330e916cff9a1ebe236725bdd\slf4j-api-1.7.19.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.5\7ed845de1dfe070d43511fab321784e6c4118398\log4j-core-2.5.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.5\e7fd981408caba8a0c0fb276413562468d260160\log4j-api-2.5.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-yaml\2.5.0\d3a9039dd90f56880ada44525ef8b1079931e571\jackson-dataformat-yaml-2.5.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-java\2.53.0\645a24b52c9e5704e900ac755b5800352e981af7\selenium-java-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.github.igor-suhorukov\chromedriver\2.21.1\842b16424d4f69a6e4600c7d8e85b4e88994814d\chromedriver-2.21.1.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-htmlunit-driver\2.52.0\b9945a26ec2518b9d094e43e7d47b8e9146d5d39\selenium-htmlunit-driver-2.52.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.sourceforge.htmlunit\htmlunit\2.20\5100a7a7c356d571471c739fbf52cc1a2e9ccf17\htmlunit-2.20.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.jsoup\jsoup\1.7.2\d7e275ba05aa380ca254f72d0c0ffebaedc3adcf\jsoup-1.7.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.joda\joda-money\0.11\9a3d8b733cb130c05376acd78e6c724e72f39d35\joda-money-0.11.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.imgscalr\imgscalr-lib\4.2\e2838f7119361511ef7d54fe0d502bf07f3325eb\imgscalr-lib-4.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-chrome-driver\2.53.0\7541a3948c3fb31122ee9633731e8103f3292b0a\selenium-chrome-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-edge-driver\2.53.0\9f3da0dfa620ae8cd71afacfdd6ddae5028ce1ea\selenium-edge-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-firefox-driver\2.53.0\5dc655b1999898d2fc3791c649b7355d98629a69\selenium-firefox-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-ie-driver\2.53.0\27b703e9fba9c0f636109cf4bd697c1f208ac825\selenium-ie-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-safari-driver\2.53.0\c80224258a8b702c99f2d7b3847ce89dc1bcd2bd\selenium-safari-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-leg-rc\2.53.0\bdabcf672449c588913ae32973dd8f7d54f510de\selenium-leg-rc-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-support\2.53.0\3706aa8a696d1b7938365a41ee7ca46309a0b2d\selenium-support-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-remote-driver\2.53.0\eb76ed037ba5a7c11cce11effd0e2175056905ac\selenium-remote-driver-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.seleniumhq.selenium\selenium-api\2.53.0\a6105ad5c43dcc02c1cf87250111b0a7f1a7c2e6\selenium-api-2.53.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.google.code.gson\gson\2.8.2\3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf\gson-2.8.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\de.slackspace\openkeepass\0.6.1\67cab94bf8b13025c9429b9687dc51d1dbfad9cd\openkeepass-0.6.1.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.5.0\489b7552dd3322b63f694122d16ce62c21c303b5\jackson-databind-2.5.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.5.0\b2ece1bd57ac7b4c315b7505b65ac79cb1da4270\jackson-core-2.5.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.12\ebe66a6b88caab31d7a19571ad23656377523545\snakeyaml-1.12.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\commons-collections\commons-collections\3.2.2\8ad72fe39fa8c91eaaf12aadb21e0c3661fe26d5\commons-collections-3.2.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents\httpmime\4.5.2\22b4c53dd9b6761024258de8f9240c3dce6ea368\httpmime-4.5.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents\httpclient\4.5.2\733db77aa8d9b2d68015189df76ab06304406e50\httpclient-4.5.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.madgag.spongycastle\core\1.54.0.0\de79c5f8c67234f0d0073e00ed1f3bab0e5d1e67\core-1.54.0.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.simpleframework\simple-xml\2.7.1\dd91fb744c2ff921407475cb29a1e3fee397d411\simple-xml-2.7.1.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.5.0\a2a55a3375bc1cef830ca426d68d2ea22961190e\jackson-annotations-2.5.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.commons\commons-exec\1.3\8dfb9facd0830a27b1b5f29f84593f0aeee7773b\commons-exec-1.3.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.java.dev.jna\jna-platform\4.1.0\23457ad1cf75c2c16763330de5565a0e67b4bc0a\jna-platform-4.1.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.java.dev.jna\jna\4.1.0\1c12d070e602efd8021891cdd7fd18bc129372d4\jna-4.1.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\io.netty\netty\3.5.7.Final\811465e6dfc89d7c78d21de6a9747b6046cb5403\netty-3.5.7.Final.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.httpcomponents\httpcore\4.4.4\b31526a230871fbe285fbcbe2813f9c0839ae9b0\httpcore-4.4.4.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\commons-logging\commons-logging\1.2\4bfc12adfe4842bf07b657f0369c4cb522955686\commons-logging-1.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\commons-codec\commons-codec\1.10\4b95f4897fa13f2cd904aee711aeafc0c5295cd8\commons-codec-1.10.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\stax\stax\1.2.0\c434800de5e4bbe1822805be5fb1c32d6834f830\stax-1.2.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\stax\stax-api\1.0.1\49c100caf72d658aca8e58bd74a4ba90fa2b0d70\stax-api-1.0.1.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\xpp3\xpp3\1.1.3.3\64f9d2bb88f58ad2a15a4301487d977ee9b4294\xpp3-1.1.3.3.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\cglib\cglib-nodep\2.1_3\58d3be5953547c0019e5704d6ed4ffda3b0c7c66\cglib-nodep-2.1_3.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\com.google.guava\guava\19.0\6ce200f6b23222af3d8abb6b6459e6c44f4bb0e9\guava-19.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\xalan\xalan\2.7.2\d55d3f02a56ec4c25695fe67e1334ff8c2ecea23\xalan-2.7.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.apache.commons\commons-lang3\3.4\5fe28b9518e58819180a43a850fbc0dd24b7c050\commons-lang3-3.4.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.sourceforge.htmlunit\htmlunit-core-js\2.17\4316d68f449d42f69faf4ee255aa31b03e4f7dd5\htmlunit-core-js-2.17.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\xerces\xercesImpl\2.11.0\9bb329db1cfc4e22462c9d6b43a8432f5850e92c\xercesImpl-2.11.0.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.sourceforge.nekohtml\nekohtml\1.9.22\4f54af68ecb345f2453fb6884672ad08414154e3\nekohtml-1.9.22.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\net.sourceforge.cssparser\cssparser\0.9.18\61c015378d27b5e245a5deb7a324c7e716b4706a\cssparser-0.9.18.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty.websocket\websocket-client\9.2.15.v20160210\ca9769107f3b8111102c5d4f482122dd116fb711\websocket-client-9.2.15.v20160210.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\xalan\serializer\2.7.2\24247f3bb052ee068971393bdb83e04512bb1c3c\serializer-2.7.2.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\xml-apis\xml-apis\1.4.01\3789d9fada2d3d458c4ba2de349d48780f381ee3\xml-apis-1.4.01.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.w3c.css\sac\1.3\cdb2dcb4e22b83d6b32b93095f644c3462739e82\sac-1.3.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty.websocket\websocket-common\9.2.15.v20160210\ee5616ec65d6c8f05fe16ee4dbb6723b2ebff470\websocket-common-9.2.15.v20160210.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty\jetty-io\9.2.15.v20160210\5a3af41803c12b0f3628ed8927a8cedb42972169\jetty-io-9.2.15.v20160210.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty\jetty-util\9.2.15.v20160210\ccd245541cc63311bdcfe551525bd7d82ea5e92c\jetty-util-9.2.15.v20160210.jar;C:\Users\guest2\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty.websocket\websocket-api\9.2.15.v20160210\f0340017129a65097824dd62a04b3c887f397dd9\websocket-api-9.2.15.v20160210.jar gui.GUI
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by de.slackspace.openkeepass.crypto.Aes (file:/C:/Users/guest2/.gradle/caches/modules-2/files-2.1/de.slackspace/openkeepass/0.6.1/67cab94bf8b13025c9429b9687dc51d1dbfad9cd/openkeepass-0.6.1.jar) to field javax.crypto.JceSecurity.isRestricted
WARNING: Please consider reporting this to the maintainers of de.slackspace.openkeepass.crypto.Aes
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
As a side note it would be great if the probably safer keepass encryption method ChaCha and Argon2 key derivation function would be supported as well.
Thank you.
It seems so that there is no implementation of using a keyfile for writing the database?
KeePassDatabase.write works only with a password.
Can you verify this?
Add a LICENSE
file to the GItHub repo. This helps people who want to use openkeepass or contribute to it, they can directly see what they are allowed to do.
I see you are using Apache 2.0 on Maven. You should add either the full text of the license (up to "END OF TERMS AND CONDITIONS") or the short version (under "APPENDIX", replace the placeholders) to the repo.
For bonus points add a link to tldrlegal at the top.
I plan to use openkeepass myself and have one or two things I'd like to contribute. :)
Hi,
I created a brand new database on KeePass 2.28 and I am able to see the entries that I create manually.
But when I save an entry using KeeFox 1.4.7 on firefox, the password is not decrypted correctly using openkeepass:
Title: Sample Entry #2 Password: 12345
Title: Sign in - Google Accounts Password: 1�
The first is an entry created on KeePass and the second created on KeeFox addon.
Cheers,
I'm currently playing around with your lib.
Opening, listing etc. works great.
But when i try to edit an entry and it contains protected fields (e.g. password), upon save, the password is "unreadable" for other keepass viewers. The testapp itself is capable of decoding the protected fields.
File extStore = Environment.getExternalStorageDirectory();
mKeePassDatabaseFile = extStore.getAbsolutePath() + "/test_simple.kdbx";
mDatabase = KeePassDatabase.getInstance(mKeePassDatabaseFile).openDatabase("test");
Group parentGroup = mDatabase.getRoot().getGroups().get(0);
Entry entry = mDatabase.getEntries().get(0);
Entry newEntry = new EntryBuilder(entry).username("hello1").buildWithHistory();
new GroupBuilder(parentGroup).removeEntry(entry).addEntry(newEntry).build();
KeePassDatabase.write(mDatabase, "test", mKeePassDatabaseFile);
Before editing the entry was: username: "user1222", password: "pwd1"
The result entry is: username "hello1", but password is "c:w�"
These results i get when:
in short: only no history and with "build()" works...
Can you please tell me what I'm doing wrong? 😢
Thanks in advance
Congratulations on this project. Would you mind, though, correcting the project description and Readme which incorrectly state
"A java library for reading and writing KeePass databases. It is the only java library that supports KeePass 2.x database files."
There are several projects here on GitHub that similarly offer Java support for Keepass 2.x data files, mine, KeepassJava2, is one of them :-)
I'm writing an Android app that uses openkeepass. When I read/write a DB, I see:
java.lang.ClassNotFoundException: Didn't find class "javax.xml.bind.JAXB" on path: DexPathList[[zip file "/data/app/tf.tom.myapplication-1/base.apk"],nativeLibraryDirectories=[/data/app/tf.tom.myapplication-1/lib/x86, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at de.slackspace.openkeepass.xml.KeePassDatabaseXmlParser.toXml(KeePassDatabaseXmlParser.java:18)
at de.slackspace.openkeepass.KeePassDatabase.write(KeePassDatabase.java:426)
The reason is that Android's javax.xml does provide the entirety of JAXB, nor does Android allow apps to include JARs that are in javax.*
This was news to me, and pretty disappointing.
Consequently, if libraries wish to be Android friendly, they should choose XML libraries other than JAXB, such as Jackson.
Would you be willing to do this? I can provide a PR, when I'm not busy.
Calling getEntryByTitle throws an IndexOutOfBounds exception if there is no entry with the passed in title.
How to reproduce:
p.s. this was working fine in 0.5.0
I get the following error with my archive:
nullpointerexception: Cannot invoke "de.slackspace.openkeepass.domain.CrsAlgorithm.ordinal()" because "algorithm" is null
at de.slackspace.openkeepass.domain.CrsAlgorithm.getIntValue(CrsAlgorithm:21)
at de.slackspace.openkeepass.domain.KeePassHeader.getInnerRandomStreamId(KeePassHeader:304)
at de.slackspace.openkeepass.domain.KeePassHeader.getValue(KeePassHeader:291)
at de.slackspace.openkeepass.domain.KeePassHeader.getHeaderSize(KeePassHeader:413)
at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptStream(KeePassDatabaseReader:114)
at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptAndParseDatabase(KeePassDatabaseReader:38)
at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase:165)
It is incorrect data check of implementation
if (storedHash == null || storedHash.length != HASH_SIZE) {
HashedBlockInputStream.java
private byte[] readStoredHashFromStream() throws IOException {
byte[] storedHash = new byte[32];
StreamUtils.read(baseStream, storedHash);
if (storedHash == null || storedHash.length != HASH_SIZE) {
throw new IOException(MSG_INVALID_DATA_FORMAT);
}
return storedHash;
}
private void fillBufferFromStream(int bufferSize) throws IOException {
buffer = new byte[bufferSize];
StreamUtils.read(baseStream, buffer);
if (buffer == null || buffer.length != bufferSize) {
throw new IOException(MSG_INVALID_DATA_FORMAT);
}
}
Hello
I'm trying to use Openkeepass to manage my KeePass 2.x databases but I'm getting a
java.lang.RuntimeException with message "Could not move right because the last node at this level has already been reached".
Here is the stack trace: Exception stacktrace.txt
My Main class contains only the main method with the instruction
KeePassFile db = KeePassDatabase.getInstance(path+"Database.kdbx").openDatabase("MasterPassword");
I've obfuscated username/passwords/notes/..., changed master password to "MasterPassword" and enclose here the zipped db: Database.zip
It's protected only with master password
I've tried to make a quick debug.
I may be wrong but it looks like the issue occurs at the root node level (I get a null parent and a current node name "Database" which is only the root).
Thanks and regards,
Mika
i create a file using KeepassDroid or KeePassFX. Then i added a group there. All works great. Decode successfully. Then I added an Entry in KeePassDroid and i have got an error when decoding:
de.slackspace.openkeepass.exception.KeePassDatabaseUnreadableException: Could not deserialize object to xml
I think, ok, maybe i can create database using this library. I did that. Encode, decode, all works great, but when I try to open this database in KeePassDroid i am getting an error:
Wrong event type
(position: TEXT 49@27:17 in java.io.inputStream ...)
whats wrong with me or with this library
Now API supports or master password either key file. KeePass tools (original and keepassx) have a possibility to set them together.
Hello
I would like to start a new database from scratch and save to a file, is ti possible to do this with the api ?
Thanks
In its current implementation, KeePassDataBase
opens a FileInputStream
that never gets closed.
Hello cternes,
I stumbled over your great library while searching for a solution for a KeePass "Automatic Password Changer".
Found nothing, so I am writing one on my own now, using your library for storage in KeePass files.
Doing so I found some issues:
Maybe I come around with some more issues when I am done with my project, if you want to hear about them.
with kind regards
HuDeanY
During refactoring between 0.4.2 and 0.5.0-SNAPSHOT entry UUID is not read from input file.
KeePassHeader.java
if (fieldId == 0) { break; }
public void read(byte[] keepassFile) throws IOException {
SafeInputStream inputStream = new SafeInputStream(new BufferedInputStream(new ByteArrayInputStream(keepassFile)));
inputStream.skipSafe(VERSION_SIGNATURE_LENGTH); // skip version
while (true) {
try {
int fieldId = inputStream.read();
byte[] fieldLength = new byte[2];
inputStream.readSafe(fieldLength);
ByteBuffer fieldLengthBuffer = ByteBuffer.wrap(fieldLength);
fieldLengthBuffer.order(ByteOrder.LITTLE_ENDIAN);
int fieldLengthInt = ByteUtils.toUnsignedInt(fieldLengthBuffer.getShort());
if (fieldLengthInt > 0) {
byte[] data = new byte[fieldLengthInt];
inputStream.readSafe(data);
setValue(fieldId, data);
}
if (fieldId == 0) {
break;
}
} catch (IOException e) {
throw new KeePassHeaderUnreadableException("Could not read header input", e);
}
}
}
de.slackspace.openkeepass.exception.KeePassDatabaseUnreadable: The key has the wrong size. Have you installed Java Cryptography Extension (JCE)? Is the master key correct?
at de.slackspace.openkeepass.crypto.Aes.transformKey(Aes.java:130)
at de.slackspace.openkeepass.crypto.Decrypter.createAesKey(Decrypter.java:49)
at de.slackspace.openkeepass.crypto.Decrypter.decryptDatabase(Decrypter.java:15)
at de.slackspace.openkeepass.KeePassDatabase.decryptAndParseDatabase(KeePassDatabase.java:316)
at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:307)
at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:280)
Hi,
What do you think about replacing simple-xml-2.7.1.jar with com.carrotsearch.thirdparty:simple-xml-safe:2.7.1 from https://github.com/carrotsearch/simplexml-safe ?
best regards,
Hi,
I am getting following exception:
Exception in thread "Root Thread" de.slackspace.openkeepass.exception.KeePassDatabaseUnreadableException: Could not decrypt keepass file. Master key wrong?
at de.slackspace.openkeepass.crypto.Aes.createCryptoException(Aes.java:115)
at de.slackspace.openkeepass.crypto.Aes.transformData(Aes.java:72)
at de.slackspace.openkeepass.crypto.Aes.decrypt(Aes.java:41)
at de.slackspace.openkeepass.crypto.Decrypter.processDatabaseEncryption(Decrypter.java:35)
at de.slackspace.openkeepass.crypto.Decrypter.decryptDatabase(Decrypter.java:16)
at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptStream(KeePassDatabaseReader.java:115)
at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptAndParseDatabase(KeePassDatabaseReader.java:38)
at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:165)
at KeepassClobUtil.getPwd(KEEPASSCLOBUTIL:299)
Caused by: java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:525)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:806)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at de.slackspace.openkeepass.crypto.Aes.transformData(Aes.java:63)
... 7 more
JVM version inside of Oracle DB version 12.2 is 1.8.0_141. I have copied latest JCE files to following directories:
/oracle/product/12.2.0.1/db_1/javavm/lib/security
/oracle/product/12.2.0.1/db_1/javavm/jdk/jdk8/lib/security
/oracle/product/12.2.0.1/db_1/jdk/jre/lib/security
I have also restarted the DB but still getting the error.
Everything works in local PC (jar built with JDK 1.8.0_141).
I have also tried to load policy files locally to server.
--load jars
declare
r varchar2(500);
begin
R := SYS.DBMS_JAVA.SET_OUTPUT_TO_SQL('1','insert into joutput values (:1)','TEXT');
SYS.DBMS_JAVA.LOADJAVA('-v -r -f /dataio/genio/projects/openkeepass/xpp3-1.1.3.3.jar');
SYS.DBMS_JAVA.LOADJAVA('-v -r -f /dataio/genio/projects/openkeepass/core-1.54.0.0.jar');
SYS.DBMS_JAVA.LOADJAVA('-v -r -f /dataio/genio/projects/openkeepass/simple-xml-2.7.1.jar');
SYS.DBMS_JAVA.LOADJAVA('-v -r -f /dataio/genio/projects/openkeepass/local_policy.jar');
SYS.DBMS_JAVA.LOADJAVA('-v -r -f /dataio/genio/projects/openkeepass/US_export_policy.jar');
end;
/
Can you give a hint ?
Hello, I was wondering if you had a rough idea of the release timing around 0.5.0? I'm currently using the SNAPSHOT version and leveraging the write aspect. Thanks for writing this BTW
Hello again)). Sorry, that I disturb you, but i can't understand, how does Entry iconData(ByteArray)
works. I tried to save byte array of my own image, but after saving, i am getting another image (standard entry image "key"). It is some strange for me. What should i do, if I want to save my own image?
I use KeeWeb on my computer to handle passwords. However, in the android app, if I open that database, the password is displayed as gibberish. If I open the same database in any other app, it works fine. If I open it elsewhere and save it, then open it via this API, it opens fine.
Database last saved by keeweb attached. Remove the .txt extension (Master password is github
)
GithubIssue.kdbx.txt
Keeweb: https://keeweb.info/
Working with jdk 1.8.151and with cryptography Extension install but have this message even if i use a 128 key length.
Is there a correction ?
Spongycastle is already deprecated, is there a reasson why you are still using it? Android, at least since API21 doen't need this anymore, and the lib hasn't seen an update in the last 3 years while bouncy gets continually updates.
Hi, I opened sorz/TinyKeePass#9 and then realized that TinyKeePass relies on this library, which is actually throwing the error.
I have a KeePass file that openkeepass cannot parse. It says "Could not deserialize object to XML." I wish I could provide the kdbx, but it contains real passwords.
The same kdbx can be opened properly with KeeWeb, KeePassDroid, and KeePass Tusk. It's possible the file is corrupted and these other tools are just very lenient when parsing the XML. I'm not sure how to check.
@Test
public void testGetGroupByUUID(){
final KeePassFile keePassFile = new KeePassFileBuilder("testDB").build();
Assert.assertEquals(keePassFile.getGroupByUUID( keePassFile.getRoot().getUuid() ), keePassFile.getRoot());
}
Hey whats the best way to add a entry to a database without changing the existing structure?
I try:
KeePassFile keeFile = KeePassDatabase.getInstance( file ).openDatabase( password );
keeFile.getEntries().add(new EntryBuilder(name)
.username(user)
.password(pass)
.build());
KeePassDatabase.write(keeFile, pass, new FileOutputStream( file ) );
It dosn't add the new key and destroy all existing passwords. On next load of the database they are all wrong.
The EntryBuilder.buildWithHistory () method there is a potential problem of circular reference.
Stack overflow exception is thrown at the timing to write the KeePassFile to file.
Circulation call occurs in Entry.hashCode () method.
@Test
public void testBuildWithHistory() {
UUID uuid = UUID.randomUUID();
Entry entry = new EntryBuilder("v1").uuid(uuid).build();
Entry entry2 = new EntryBuilder(entry).title("v2").buildWithHistory();
Entry entry3 = new EntryBuilder(entry2).title("v3").buildWithHistory();
try{
entry.hashCode();
entry2.hashCode();
entry3.hashCode();
}catch(StackOverflowError e){
e.printStackTrace();
Assert.fail();
}
}
Hi,
I started using this library in one of my use case where my team members access password for different servers stored in the keepass file frequently. In my testing after calling the below code probably after 10times my micro services crashes. I have 1GB allocated to my service.
KeePassDatabase.getInstance(keepassFileinputStream).openDatabase("password",keyfileInputStream);
Is this something you could check and fix this memory leak?
Thanks,
Murthy
BC 1.50 introduced a non backwards compatible change in StreamCipher#processBytes
, which now returns an int
instead of void
.
This change is source compatible (meaning openkeepass can recompile without a change to BC 1.49 and less), but not binary compatible, one gets the following error :
java.lang.NoSuchMethodError: org.bouncycastle.crypto.engines.Salsa20Engine.processBytes([BII[BI)I
While not an issue with this implementation in and of itself, this forces applications to upgrade BouncyCastle to 1.50+, which can be expansive.
Would you consider a change (or a pull request) to refactor Salsa20
, using a reflection based appraoch to mitigate the issue ?
I'm thinking something along the lines of :
import org.bouncycastle.crypto.engines.Salsa20Engine;
public class Salsa20EngineAdapter extends Salsa20Engine {
private static final String PROCESS_BYTES_METHOD = "processBytes";
private static final Class<?>[] PROCESS_BYTES_ARG = new Class[] { byte[].class, Integer.TYPE, Integer.TYPE, byte[].class, Integer.TYPE };
public void adaptProcessBytes(byte[] in, int inOff, int len, byte[] out, int outOff) {
try {
// BouncyCastle 1.50 and above
super.processBytes(in, inOff, len, out, outOff);
} catch (NoSuchMethodError e) {
// In BC 1.49 and below, #processBytes() returns void instead of int, this breaks binary compatibilty
// http://stackoverflow.com/a/3589948/2131074
try {
Method processBytesMethod = Salsa20Engine.class.getMethod(PROCESS_BYTES_METHOD, PROCESS_BYTES_ARG);
processBytesMethod.invoke(this, in, inOff, len, out, outOff);
} catch (Exception e1) {
// Ignore e1, rethrow e
throw e;
}
}
}
}
Reproducing the behaviour needs a separate project importing openkeepass, but excluding the BC dependency with an older version.
I cannot open my database file. I get the following error below. I am using KeePassXC v2.5.3 with a MasterPassword to open the file, and the database format is KDBX 4.0. It doesn't seem like the API supports KDBX 4.0.
java.lang.NullPointerException at de.slackspace.openkeepass.domain.CrsAlgorithm.getIntValue(CrsAlgorithm.java:21) at de.slackspace.openkeepass.domain.KeePassHeader.getInnerRandomStreamId(KeePassHeader.java:304) at de.slackspace.openkeepass.domain.KeePassHeader.getValue(KeePassHeader.java:291) at de.slackspace.openkeepass.domain.KeePassHeader.getHeaderSize(KeePassHeader.java:413) at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptStream(KeePassDatabaseReader.java:114) at de.slackspace.openkeepass.api.KeePassDatabaseReader.decryptAndParseDatabase(KeePassDatabaseReader.java:38) at de.slackspace.openkeepass.KeePassDatabase.openDatabase(KeePassDatabase.java:165)
With the current setup, editing an entry is a challenge. One needs the entry to show the current information but you need an entry builder to actually update the entry. GUI wise this is kind of a hell toggling between two different objects to handle this.
Is this usecase not in view for this project? or is there another pattern in use here?
Hello, I created a file.kdbx with your library. I added there an entry, group. All works great. I saved this file, opened it again in my app, all works great. But if i try to open this file by KeePassDroid I am getting an error:
What went wrong?
Here is link for my kdbx file
https://vk.com/doc139236776_469854622?hash=93df14818ed1dad713&dl=918099d4e1c206eafc
The password is: 1
I will happy if you will fix this bug
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.