This is an example Java/Maven project demonstrating the use of Voltage SimpleAPI to perform fast and efficient data protection with Format Preserving Encryption (NIST FF1).
See your Voltage Professional Services representative to obtain the SimpleAPI binaries. The following items are not published to public repos, but are needed for execution:
- cache/ — directory to hold the policy cache
- libs/ — external libraries
- libvibesimplejava.dylib — native dynamic library
- vibesimplejava.jar — Java archive (import com.voltage.securedata.enterprise)
- trustStore/ — certificates for your Voltage appliance
You can build this project with the following commands (builds a single fat-jar):
# Installs the Voltage Simple API jar (import com.voltage.securedata.enterprise)mvn install:install-file -Dfile=libs/vibesimplejava.jar -DgroupId=com.voltage -DartifactId=vibesimplejava -Dversion=1.0 -Dpackaging=jar
# Clean buildmvn clean packageThe Java is setup so that passwords and other sensitive info are contained in a ".env" file within the project root (create it; excluded with .gitignore):
ora.user="VOLTAGE"ora.password="password"ora.host="hostname.oraclecloud.com"ora.service="oracle19c.adb.oraclecloud.com"voltage.secret="sharedsecret"voltage.host="appliance.voltage.com"voltage.id="identity"And run with these commands:
# Run against data.csv as a sourcejava -Djava.library.path=libs -jar target/protection-1.0.jar "data.csv"
# Run against Oracle as a sourcejava -Djava.library.path=libs -jar target/protection-1.0.jar --oracleOptionally use these commands to run without a fat-jar:
java -cp "target/protection-1.0.jar:libs/*" -Djava.library.path=libs com.opentext.voltage.Protection "data.csv"java --enable-native-access=ALL-UNNAMED -cp "target/protection-1.0.jar:libs/*" -Djava.library.path=libs com.opentext.voltage.Protection "../data.csv"The command line will output:
root@localhost protection % java -Djava.library.path=libs -jar target/protection-1.0.jar --oracleExports will save to: "/Voltage/Java/protection/"Jdbc Url: "jdbc:oracle:thin:@(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=<host>))(connect_data=(service_name=<service>))(security=(ssl_server_dn_match=yes)))"Query: "SELECT * FROM data ORDER BY id"Total rows ingested = 5000API Version: Simple API Java 6.22.0.5Identity: "sampleidentity:070101000000Z:dataprotection.voltage.com#1188515279:data:FPE:256::"FPE test --> Cleartext: "Hello World" Ciphertext: "Eujne Ootlc" Cleartext: "123-45-6789" Ciphertext: "762-48-6789" Cleartext: "01-01-2026" Ciphertext: "03-23-2007" Cleartext: "1111-2222-3333-4444" Ciphertext: "1111-22T5-CFBD-4444" Cleartext: "02/2027" Ciphertext: "07/2067"Dummy enumerator block executed in 3.520125 msEmpty enumerator block executed in 0.373375 msProtect block executed in 26.304667 msCSV exported to "/Voltage/Java/protection/protected-ORACLE.data.csv"Unprotect block executed in 25.874417 msCSV exported to "/Voltage/Java/protection/unprotected-ORACLE.data.csv"The code uses a Timer class to calculate code execution time to the nano-second precision. As you can see from above, BLAZING FAST speed.
Timertimer = newTimer(); // Stopwatch instancetimer.reset(); // reset the counterout("Elapsed time = " + timer.elapsed() + " ms"); // print elapsed timestaticclassTimer { // Stopwatch-timer classprivatelongstart; // holds the start time in nanosecondspublicTimer() { start = System.nanoTime(); }
publicdoubleelapsed() { // milliseconds w/nano decimal partreturn (System.nanoTime() - start) / 1_000_000.0;
}
publicvoidreset() { start = System.nanoTime(); }
}The DDL to make an Oracle data source:
CREATEUSERVOLTAGE IDENTIFIED BY "password";
GRANT CREATE SESSION TO VOLTAGE;
GRANT CREATE TABLE TO VOLTAGE;
GRANT UNLIMITED TABLESPACE TO VOLTAGE;
CREATETABLEVOLTAGE.data (
id NUMBERPRIMARY KEY,
name VARCHAR2(75),
ssn VARCHAR2(11),
dob VARCHAR2(10),
card VARCHAR2(19),
exp VARCHAR2(7)
);
GRANTSELECT, INSERT ONVOLTAGE.data TO VOLTAGE;
SELECT*fromVOLTAGE.DATAORDER BY idA "data.csv" is provided in this example. It is also the default value should you not provide any argument to the command at runtime.
| id | name | ssn | dob | card | exp |
|---|---|---|---|---|---|
| 1 | Amy Nelson | 360-26-1232 | 09-21-1979 | 1969-8999-6827-5777 | 04/2026 |
| 2 | Betty Hernandez | 745-46-3763 | 09-18-2011 | 4807-9987-5584-9969 | 09/2027 |
| 3 | Fiona Cook | 762-85-6426 | 03-21-1977 | 5957-4081-1071-9407 | 07/2026 |
| 4 | Aiden Martin | 895-61-3408 | 11-02-2018 | 2905-2293-7691-6411 | 06/2026 |
| 5 | Arthur Walker | 586-89-8812 | 08-03-1964 | 7925-4193-6516-6129 | 06/2026 |
After protection, the data will appear as:
| id | name | ssn | dob | card | exp |
|---|---|---|---|---|---|
| 1 | Nzr Dtcmsq | 328-52-1232 | 12-29-1963 | 1969-89LE-K89T-5777 | 08/1976 |
| 2 | Pdrfn Tubklaipy | 463-57-3763 | 09-27-1984 | 4807-99AU-EEYF-9969 | 08/2066 |
| 3 | Ziltt Lgkg | 119-25-6426 | 08-26-1981 | 5957-40EE-V5VL-9407 | 10/1994 |
| 4 | Tuucj Vubmhq | 531-45-3408 | 08-01-1953 | 2905-22KJ-Q4VL-6411 | 10/2130 |
| 5 | Cppbvb Dstldn | 456-76-8812 | 02-19-2029 | 7925-41N7-02GF-6129 | 10/2130 |
This data can be re-created by running:
# Generates 5,000 rows of sample datapython3 data-generate.pyAnd then pushed up to Oracle by:
# Pushes to the DSN in your ".env" filepython3 data-oraclepush.py