Awesome Open Source
Awesome Open Source

Secret Service

Maven Central

A Java library for storing secrets in a keyring over the D-Bus.

The library is conform to the freedesktop.org Secret Service API 0.2 and thus compatible with Gnome linux systems.

The Secret Service itself is implemented by the gnome-keyring and provided by the gnome-keyring-daemon.

This library can be seen as the functional equivalent to the libsecret C client library.

Related

For KDE systems there is the kdewallet client library, kindly provided by @purejava.

Security Issues

CVE-2018-19358 (Vulnerability)

There is a current investigation on the behaviour of the Secret Service API, as other applications can easily read any secret, if the keyring is unlocked (if a user is logged in, then the login/default collection is unlocked). Available D-Bus protection mechanisms (involving the busconfig and policy XML elements) are not used by default. The Secret Service API was never designed with a secure retrieval mechanism.

Usage

The library provides a simplified high-level API, which sends only transport encrypted secrets over the D-Bus.

Dependency

Add the secret-service as dependency to your project. You may want to exclude the slf4j-api if you use an incompatible version.

<dependency>
    <groupId>de.swiesend</groupId>
    <artifactId>secret-service</artifactId>
    <version>1.7.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

High-Level API

public class Example {

    @Test
    @DisplayName("Create a password in the user's default collection (/org/freedesktop/secrets/aliases/default).")
    public void createPasswordInDefaultCollection() throws IOException, AccessControlException, IllegalArgumentException {
        try (SimpleCollection collection = new SimpleCollection()) {
            String item = collection.createItem("My Item", "secret");

            char[] actual = collection.getSecret(item);
            assertEquals("secret", new String(actual));
            assertEquals("My Item", collection.getLabel(item));

            collection.deleteItem(item);
        } // clears automatically all session secrets in memory, but does not close the D-Bus connection.
    }

    @Test
    @DisplayName("Create a password in a non-default collection (/org/freedesktop/secrets/collection/xxx).")
    public void createPasswordInNonDefaultCollection() throws IOException, AccessControlException, IllegalArgumentException {
        try (SimpleCollection collection = new SimpleCollection("My Collection", "super secret")) {
            String item = collection.createItem("My Item", "secret");

            char[] actual = collection.getSecret(item);
            assertEquals("secret", new String(actual));
            assertEquals("My Item", collection.getLabel(item));

            collection.deleteItem(item);
            collection.delete();
        } // clears automatically all session secrets in memory, but does not close the D-Bus connection.
    }

    @Test
    @DisplayName("Create a password with additional attributes.")
    public void createPasswordWithAttributes() throws IOException, AccessControlException, IllegalArgumentException {
        try (SimpleCollection collection = new SimpleCollection("My Collection", "super secret")) {
            // define unique attributes
            Map<String, String> attributes = new HashMap();
            attributes.put("uuid", "42");

            // create and forget
            collection.createItem("My Item", "secret", attributes);

            // find by attributes
            List<String> items = collection.getItems(attributes);
            assertEquals(1, items.size());
            String item = items.get(0);

            char[] actual = collection.getSecret(item);
            assertEquals("secret", new String(actual));
            assertEquals("My Item", collection.getLabel(item));
            assertEquals("42", collection.getAttributes(item).get("uuid"));

            collection.deleteItem(item);
            collection.delete();
        } // clears automatically all session secrets in memory, but does not close the D-Bus connection.
    }

    // The D-Bus connection gets closed at the end of the static lifetime of `SimpleCollection` by a shutdown hook.

}

Closing the D-Bus connection:

The D-Bus connection is closed eventually at end of the static lifetime of SimpleCollection with a shutdown hook and not by auto-close. One can also close the D-Bus connection manually by calling SimpleCollection.disconnect(), but once disconnected it is not possible to reconnect.

SimpleCollection-Interface:

For Further methods and attributes checkout the SimpleCollection-Interface.

Transport Encryption:

For the details of the transport encryption see: Transfer of Secrets, Transport Encryption Example

Low-Level API

The low-level API gives access to all defined D-Bus Methods, Properties and Signals of the Secret Service interface:

For the usage of the low-level API see the tests:

D-Bus Interfaces

The underlying introspected XML D-Bus interfaces are available as resources.

Contributing

You are welcome to point out issues, file PRs and comment on the project.

Please keep in mind that this is a non-profit effort in my spare time and thus it may take some time until issues are addressed.

Thank You

Special thanks goes out to


Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Java (710,532
Scala (39,288
Linux (16,549
Password (1,645
Jvm (1,051
Gnome (735
Java Library (696
Secrets (587
Dbus (224
Password Store (186
Related Projects