Initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>rs.in.zivanovic</groupId>
|
||||
<artifactId>j-password-obfuscator</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<name>JPasswordObfuscator</name>
|
||||
<description>
|
||||
Extensible Java library and command line utility for sensitive data obfuscation and de-obfuscation.
|
||||
Solution for protecting passwords and other sensitive data in configuration files or in transit from casual glances.
|
||||
Not at all useful for protecting sensitive data from attackers bent on stealing your secrets.
|
||||
</description>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT license</name>
|
||||
<url>http://opensource.org/licenses/MIT</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>marko</id>
|
||||
<name>Marko Zivanovic</name>
|
||||
<email>marko@zivanovic.in.rs</email>
|
||||
<url>http://marko.zivanovic.in.rs</url>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<organization>
|
||||
<name>Marko Zivanovic</name>
|
||||
<url>http://marko.zivanovic.in.rs</url>
|
||||
</organization>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.52</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>rs.in.zivanovic.obfuscator.Run</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator;
|
||||
|
||||
import java.util.Objects;
|
||||
import rs.in.zivanovic.obfuscator.impl.ObfuscatedData;
|
||||
import rs.in.zivanovic.obfuscator.impl.Obfuscator;
|
||||
import rs.in.zivanovic.obfuscator.impl.V1ObfuscatorImpl;
|
||||
|
||||
/**
|
||||
* Obfuscate and de-obfuscate sensitive data.
|
||||
*
|
||||
* This method is useful for protecting potentially sensitive data from casual onlookers. It is NOT secure against
|
||||
* attackers with access to source code or live systems.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public final class JPasswordObfuscator {
|
||||
|
||||
private final Obfuscator v1Obfuscator = new V1ObfuscatorImpl();
|
||||
|
||||
/**
|
||||
* Obfuscate data using supplied master key and current algorithm version.
|
||||
*
|
||||
* @param masterKey master key to use for obfuscation
|
||||
* @param data data to obfuscate
|
||||
*
|
||||
* @return string containing obfuscated data; use {@link #deObfuscate} to get secret data from this string
|
||||
*/
|
||||
public String obfuscate(char[] masterKey, byte[] data) {
|
||||
return obfuscate(masterKey, data, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscate data using supplied master key and algorithm version.
|
||||
*
|
||||
* @param masterKey master key to use for obfuscation
|
||||
* @param data data to obfuscate
|
||||
* @param version obfuscation algorithm version to use
|
||||
*
|
||||
* @return string containing obfuscated data; use {@link #deObfuscate} to get secret data from this string
|
||||
*/
|
||||
public String obfuscate(char[] masterKey, byte[] data, int version) {
|
||||
Objects.requireNonNull(masterKey);
|
||||
Objects.requireNonNull(data);
|
||||
switch (version) {
|
||||
case 1:
|
||||
return v1Obfuscator.obfuscate(masterKey, data).toString();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported version: " + version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* De-obfuscate string generated with {@link #obfuscate} method.
|
||||
*
|
||||
* @param masterKey master key to use for de-obfuscation; must match the key used for obfuscation
|
||||
* @param obfuscatedString obfuscated string generated using one of {@link #obfuscate} methods
|
||||
*
|
||||
* @return original, de-obfuscated data
|
||||
*/
|
||||
public byte[] deObfuscate(char[] masterKey, String obfuscatedString) {
|
||||
Objects.requireNonNull(masterKey);
|
||||
Objects.requireNonNull(obfuscatedString);
|
||||
ObfuscatedData ob = ObfuscatedData.fromString(obfuscatedString);
|
||||
switch (ob.version) {
|
||||
case 1:
|
||||
return v1Obfuscator.deObfuscate(masterKey, ob);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported version: " + ob.version);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Command line interface for obfuscating and de-obfuscating data.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public class Run {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 3) {
|
||||
showHelp();
|
||||
} else {
|
||||
switch (args[0]) {
|
||||
case "o":
|
||||
obfuscate(args);
|
||||
break;
|
||||
case "d":
|
||||
deObfuscate(args);
|
||||
break;
|
||||
default:
|
||||
showHelp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void showHelp() {
|
||||
System.out.println(String.format("Data obfuscation / de-obfuscation tool"));
|
||||
System.out.
|
||||
println(String.format("Syntax: java -jar <file.jar> <operation> <master key> <data to de/obfuscate>"));
|
||||
System.out.println(String.format(" <operation> - 'o' - obfuscate, 'd' - de-obfuscate"));
|
||||
|
||||
}
|
||||
|
||||
private static void deObfuscate(String[] args) {
|
||||
char[] masterKey = args[1].toCharArray();
|
||||
String data = args[2];
|
||||
System.out.println(new String(new JPasswordObfuscator().deObfuscate(masterKey, data), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private static void obfuscate(String[] args) {
|
||||
char[] masterKey = args[1].toCharArray();
|
||||
byte[] data = args[2].getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(new JPasswordObfuscator().obfuscate(masterKey, data));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator.impl;
|
||||
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
/**
|
||||
* Container for obfuscated data.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public class ObfuscatedData {
|
||||
|
||||
private static final String SIGNATURE = "rizobf";
|
||||
public final int version;
|
||||
public final byte[] salt;
|
||||
public final byte[] cipherText;
|
||||
|
||||
public ObfuscatedData(int version, byte[] salt, byte[] cipherText) {
|
||||
this.version = version;
|
||||
this.salt = salt;
|
||||
this.cipherText = cipherText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("$%s$%d$%s$%s", SIGNATURE, version, Base64.toBase64String(salt),
|
||||
Base64.toBase64String(cipherText));
|
||||
}
|
||||
|
||||
public static ObfuscatedData fromString(String obfuscatedString) {
|
||||
String[] parts = obfuscatedString.split("\\$");
|
||||
if (parts.length != 5) {
|
||||
throw new IllegalArgumentException("Invalid obfuscated data");
|
||||
}
|
||||
if (!parts[1].equals(SIGNATURE)) {
|
||||
throw new IllegalArgumentException("Invalid obfuscated data");
|
||||
}
|
||||
return new ObfuscatedData(Integer.parseInt(parts[2]), Base64.decode(parts[3]), Base64.decode(parts[4]));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator.impl;
|
||||
|
||||
/**
|
||||
* Obfuscator/de-obfuscator interface.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public interface Obfuscator {
|
||||
|
||||
/**
|
||||
* Obfuscate sensitive data using supplied master key.
|
||||
*
|
||||
* @param masterKey master key to use for data obfuscation
|
||||
* @param data sensitive data to obfuscate
|
||||
*
|
||||
* @return obfuscated string
|
||||
*/
|
||||
ObfuscatedData obfuscate(char[] masterKey, byte[] data);
|
||||
|
||||
/**
|
||||
* De-obfuscate data using supplied master key.
|
||||
*
|
||||
* @param masterKey master key to use for data de-obfuscation; must match master key used for obfuscation
|
||||
* @param data string obfuscated with {@link #obfuscate} to de-obfuscate
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
byte[] deObfuscate(char[] masterKey, ObfuscatedData data);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator.impl;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Random;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
/**
|
||||
* Password Based Encryption (PBE) based obfuscator. Use as a base class for further specializations.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public class PBEObfuscatorImpl implements Obfuscator {
|
||||
|
||||
private final int version;
|
||||
private final String algo;
|
||||
private final String provider;
|
||||
private final int iterations;
|
||||
private final int saltLen;
|
||||
|
||||
public PBEObfuscatorImpl(int version, String algo, String provider, int iterations, int saltLen) {
|
||||
this.algo = algo;
|
||||
this.provider = provider;
|
||||
this.iterations = iterations;
|
||||
this.saltLen = saltLen;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObfuscatedData obfuscate(char[] masterKey, byte[] data) {
|
||||
try {
|
||||
byte[] salt = generateRandomSalt();
|
||||
byte[] cipher = crypto(Cipher.ENCRYPT_MODE, data, masterKey, salt);
|
||||
return new ObfuscatedData(version, salt, cipher);
|
||||
} catch (GeneralSecurityException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deObfuscate(char[] masterKey, ObfuscatedData ob) {
|
||||
try {
|
||||
return crypto(Cipher.DECRYPT_MODE, ob.cipherText, masterKey, ob.salt);
|
||||
} catch (GeneralSecurityException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] crypto(int mode, byte[] input, char[] masterKey, byte[] salt) throws IllegalBlockSizeException,
|
||||
InvalidKeyException, NoSuchAlgorithmException, BadPaddingException, NoSuchProviderException,
|
||||
NoSuchPaddingException, InvalidKeySpecException {
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo, provider);
|
||||
PBEKeySpec ks = new PBEKeySpec(masterKey, salt, iterations);
|
||||
SecretKey sk = skf.generateSecret(ks);
|
||||
Cipher c = Cipher.getInstance(algo, provider);
|
||||
c.init(mode, sk);
|
||||
return c.doFinal(input);
|
||||
}
|
||||
|
||||
private byte[] generateRandomSalt() throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
Random random = SecureRandom.getInstance("SHA1PRNG");
|
||||
byte[] salt = new byte[saltLen];
|
||||
random.nextBytes(salt);
|
||||
return salt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator.impl;
|
||||
|
||||
import java.security.Security;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
/**
|
||||
* PBE-based obfuscator using <em>PBEWithSHA256And128BitAES</em> algorithm with 16,000 rounds, 8 bytes of randomly
|
||||
* generated salt and BouncyCastle as crypto provider.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public class V1ObfuscatorImpl extends PBEObfuscatorImpl {
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
private static final int VERSION = 1;
|
||||
private static final String PROVIDER = "BC";
|
||||
private static final String ALGO = "PBEWithSHA256And128BitAES-CBC-BC";
|
||||
private static final int SALT_LEN = 8;
|
||||
private static final int ITERATION_COUNT = 16_000;
|
||||
|
||||
public V1ObfuscatorImpl() {
|
||||
super(VERSION, ALGO, PROVIDER, ITERATION_COUNT, SALT_LEN);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2015 Marko Zivanovic <marko@zivanovic.in.rs>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package rs.in.zivanovic.obfuscator;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Obfuscator unit tests.
|
||||
*
|
||||
* @author Marko Zivanovic <marko@zivanovic.in.rs>
|
||||
*/
|
||||
public class JPasswordObfuscatorTest {
|
||||
|
||||
private static final char[] masterKey = "masterKey".toCharArray();
|
||||
private static final char[] masterKey1 = "masterKey1".toCharArray();
|
||||
private static final char[] masterKey2 = "masterKey2".toCharArray();
|
||||
private static final byte[] data = "data".getBytes(StandardCharsets.UTF_8);
|
||||
private final JPasswordObfuscator engine = new JPasswordObfuscator();
|
||||
|
||||
@Test
|
||||
public void testObfuscateDeObfuscate() {
|
||||
String ob = engine.obfuscate(masterKey, data);
|
||||
System.out.println(ob);
|
||||
byte[] deob = engine.deObfuscate(masterKey, ob);
|
||||
assertArrayEquals(data, deob);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testObfuscateInvalidVersion() {
|
||||
String ob = engine.obfuscate(masterKey, data, 123);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testObfuscateDeObfuscateWrongMasterKey() {
|
||||
String ob = engine.obfuscate(masterKey1, data);
|
||||
byte[] deob = engine.deObfuscate(masterKey2, ob);
|
||||
assertThat(data, not(equalTo(deob)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObfuscateTiming() {
|
||||
int timing_length = 3;
|
||||
long start = System.currentTimeMillis();
|
||||
long count = 0;
|
||||
while (System.currentTimeMillis() - start < timing_length * 1_000) {
|
||||
count++;
|
||||
engine.obfuscate(masterKey, data);
|
||||
}
|
||||
System.out.println(String.format("%d iterations in %d seconds, %.2f iterations per second", count,
|
||||
timing_length, (float) count / timing_length));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testObfuscateNullData() {
|
||||
engine.obfuscate(masterKey, null);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testObfuscateNullMasterKey() {
|
||||
engine.obfuscate(null, data);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testDeobfuscateNullData() {
|
||||
engine.deObfuscate(masterKey, null);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testDeobfuscateGarbageData() {
|
||||
engine.deObfuscate(masterKey, "23499999puchn-p23948hfrn-[8f2333331xd");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDeobfuscateInvalidSignature() {
|
||||
engine.deObfuscate(masterKey, "$INV$1$v1hACmQULBk=$ggRxqVe1fUMvUnzpLA6CoQ==");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDeobfuscateTruncated() {
|
||||
engine.deObfuscate(masterKey, "$rizobf$1$v1hACmQULBk=$");
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testDeobfuscateInvalidData() {
|
||||
engine.deObfuscate(masterKey, "$rizobf$1$v1hACmQULBk=$ggRxqVe1fUMvUnzpLA6Coq");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDeobfuscateInvalidVersion() {
|
||||
engine.deObfuscate(masterKey, "$rizobf$211$v1hACmQULBk=$ggRxqVe1fUMvUnzpLA6Coq");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user