Home

Awesome

WinDPAPI4J: A Windows DPAPI Wrapper for Java

Introduction

Starting from Microsoft(R) Windows(R) 2000, Windows operating systems provide a built-in cryptographic feature called "Windows Data Protection API" (DPAPI), which allows any application to securely encrypt confidential user data using the user's credentials in a way that it can only be decrypted by the same user.

This Java library exposes Windows Data Protection encryption and decryption features as an easy to use Java API. Behind the scenes, JNA (Java Native Access) library is used to invoke the native Windows CryptoAPI CryptProtectData and CryptUnprotectData functions.

Note:

The JavaDoc is part of the Maven Central installation and can be viewed online via javadoc.io

Passing special flags to Windows DPAPI

As described in Microsoft Development Network Documentation on Cryptography Functions, both CryptProtectData and CryptUnprotectData functions accept optional flag values, which control their behaviour.

These optional flag values are defined in WinDPAPI.CryptProtectFlag as enum constants and can be passed to the static factory method WinDPAPI#newInstance(CryptProtectFlag...) after which the WinDPAPI instance returned will pass them to the target native Windows DPAPI method.

Mapping of methods

Methods for encryption

WinDPAPI library methodsWindows CryptoAPI method
WinDPAPI#protectData(byte[])CryptProtectData
WinDPAPI#protectData(byte[], byte[])CryptProtectData
WinDPAPI#protectData(byte[], byte[], java.lang.String)CryptProtectData

Methods for decryption

WinDPAPI library methodsWindows CryptoAPI method
WinDPAPI#unprotectData(byte[])CryptUnprotectData
WinDPAPI#unprotectData(byte[], byte[])CryptUnprotectData

Sample Code

package sample;
  
import com.github.windpapi4j.WinDPAPI;
import com.github.windpapi4j.WinDPAPI.CryptProtectFlag;

public class Sample {

    public static void main(String[] args) throws Exception {

        if(WinDPAPI.isPlatformSupported()) {
            WinDPAPI winDPAPI = WinDPAPI.newInstance(CryptProtectFlag.CRYPTPROTECT_UI_FORBIDDEN);

            String message = "Hello World!";
            String charsetName = "UTF-8";

            byte[] clearTextBytes = message.getBytes(charsetName);

            byte[] cipherTextBytes = winDPAPI.protectData(clearTextBytes);

            byte[] decryptedBytes = winDPAPI.unprotectData(cipherTextBytes);

            String decryptedMessage = new String(decryptedBytes, charsetName);

            if(! message.equals(decryptedMessage) ) {
                // should not happen
                throw new IllegalStateException(message + " != " + decryptedMessage); 
            }

            System.out.println(decryptedMessage);

        } else {
            System.err.println("ERROR: platform not supported");
        }
    }
}

Availability

This library has been made available in Maven Central Repository.