com.dyadicsec.advapi.SDESessionKey Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.dyadicsec.advapi;
import com.dyadicsec.pkcs11.CKException;
import com.dyadicsec.pkcs11.CKSecretKey;
import com.dyadicsec.pkcs11.DYCK_FPE_PARAMS;
import com.unbound.common.crypto.FPE;
import com.unbound.common.crypto.HMAC;
import com.unbound.common.crypto.SPE;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.TimeZone;
/**
* This class includes methods for application level encryption using a derived data encryption key (DEK), see Application-Level Encryption in the UKC Developers Guide for more information.
*/
public class SDESessionKey
{
private int purpose;
SDEKey sdeKey = null;
CKSecretKey secretKey = null;
byte[] rawKey = null;
SDESessionKey(SDEKey sdeKey, int purpose, CKSecretKey secretKey)
{
this.secretKey = secretKey;
this.sdeKey = sdeKey;
this.purpose = purpose;
}
SDESessionKey(SDEKey sdeKey, int purpose, byte[] rawKey)
{
this.rawKey = rawKey;
this.sdeKey = sdeKey;
this.purpose = purpose;
}
@Override
protected void finalize()
{
destroy();
}
public void destroy()
{
if (secretKey == null) return;
try
{
secretKey.destroy();
}
catch (CKException e)
{
}
secretKey = null;
}
public byte[] getKeyMaterial()
{
if (rawKey!=null) return rawKey;
try
{
return secretKey.getValue();
}
catch (CKException e)
{
return null;
}
}
/**
* Get the SDEKey used to derive this date encryption key
*
* @return The SDEKey used for this data encryption key derivation
*/
public SDEKey getSDEKey()
{
return sdeKey;
}
private static final int ONEWAY_TOKEN_SIZE = 16;
/**
* Creates a unique searchable token from a byte array
*
* @param in The input data
* @return Searchable token of size 16 bytes
* @throws SecurityException In case of encryption error
*/
public byte[] encryptPRF(byte[] in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_ONE_WAY) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return HMAC.SHA256.hmac(rawKey, in);
}
try
{
return secretKey.hmacSha256(in);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Creates a unique searchable token from a byte array
*
* @param data The input data
* @return Searchable token of size 16 bytes
* @throws SecurityException In case of encryption error
*/
public String encryptPRF(final String data) throws SecurityException
{
try
{
byte[] encData = encryptPRF(data.getBytes("UTF8"));
return SDEUtils.bytesToStringTP(encData);
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
}
private byte[] encryptTypePreserving(byte[] in, int bits) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_SP_ENC) throw new IllegalArgumentException("Invalid purpose");
if ((in.length < 16) && ((bits % 2) != 0) && bits != 1)
throw new IllegalArgumentException("Byte array input for type preserving encryption cannot be odd and less then 16 bytes");
if (rawKey!=null)
{
return SPE.encrypt(rawKey, in, bits);
}
try
{
return secretKey.encryptSPE(in, bits);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a byte array
*
* @param in The data to encrypt, the length of the array should be even or at least 16 bytes
* @return The encrypted value, the size of the encrypted data equals to the size of the input
* @throws SecurityException In case of encryption error
*/
public byte[] encryptTypePreserving(byte[] in) throws SecurityException
{
return encryptTypePreserving(in, in.length * 8);
}
private byte[] decryptTypePreserving(byte[] in, int bits) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_SP_ENC) throw new IllegalArgumentException("Invalid purpose");
if ((in.length < 16) && ((bits % 2) != 0) && bits != 1)
throw new IllegalArgumentException("Byte array input for type preserving decryption cannot be odd and less then 16 bytes");
if (rawKey!=null)
{
return SPE.decrypt(rawKey, in, bits);
}
try
{
return secretKey.decryptSPE(in, bits);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt a byte array
*
* @param in The encrypted data
* @return Decrryped byte array
* @throws SecurityException In case of decryption error
*/
public byte[] decryptTypePreserving(byte[] in) throws SecurityException
{
return decryptTypePreserving(in, in.length * 8);
}
/**
* Encrypt a string value
*
* @param in The data to encrypt
* @param BMPOnly Determines if the plain and cipher text includes only Unicode Basic Multilingual Plane codes
* or all Unicode planes. BMP plain should be suitable for most of the use cases and
* has a more compact byte representation. Set to false if the full set of Unicode codes is
* required. For more information on Unicode planes,
* see https://en.wikipedia.org/wiki/Plane_(Unicode)
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptTypePreserving(String in, boolean BMPOnly) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_STRING_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.STR.encrypt(rawKey, in, BMPOnly);
}
try
{
String format = BMPOnly ? "ISO-10646-UCS-2" : "UTF-16BE";
return secretKey.encryptStringFPE(in, format);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* DEcrypt a string value
*
* @param in The data to decrypt
* @param BMPOnly Determines if the plain and cipher text includes only Unicode Basic Multilingual Plane codes
* or all Unicode planes. BMP plain should be suitable for most of the use cases and
* has a more compact byte representation. Set to false if the full set of Unicode codes is
* required. For more information on Unicode planes,
* see https://en.wikipedia.org/wiki/Plane_(Unicode)
* @return Plain value
* @throws SecurityException In case of encryption error
*/
public String decryptTypePreserving(String in, boolean BMPOnly) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_STRING_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.STR.decrypt(rawKey, in, BMPOnly);
}
try
{
String format = BMPOnly ? "ISO-10646-UCS-2" : "UTF-16BE";
return secretKey.decryptStringFPE(in, format);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a string value in order preserving form
*
* @param data The data to encrypt
* @param size Maximum size of values that should be compared with this value
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptOrderPreserving(String data, int size) throws SecurityException
{
try
{
byte[] dataBytes = data.getBytes("UTF8");
dataBytes = SDEUtils.addTailing(dataBytes, (byte) 0, size - dataBytes.length);
byte[] encData = encryptOPE(dataBytes);
return SDEUtils.bytesToStringOP(encData);
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt a string value encrypted with order preserving encryption
*
* @param encDataStr The encrypted value
* @return String value in plain
* @throws SecurityException In case of decryption error
*/
public String decryptOrderPreserving(String encDataStr) throws SecurityException
{
try
{
byte[] encData = SDEUtils.stringToBytesOP(encDataStr);
byte[] data = decryptOPE(encData);
data = SDEUtils.removeTailing(data, (byte) 0);
return new String(data, "UTF8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
}
byte[] encryptOPE(byte[] in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_OP_ENC) throw new IllegalArgumentException("Invalid purpose");
try
{
return secretKey.encryptOPE(in);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
byte[] decryptOPE(byte[] in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_OP_ENC) throw new IllegalArgumentException("Invalid purpose");
try
{
return secretKey.decryptOPE(in);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a long value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public long encryptTypePreserving(long data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(data).array();
byte[] encData = encryptTypePreserving(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData); // big-endian by default
return wrapped.getLong();
}
/**
* Decrypt an encryptyed long value
*
* @param encData The encrypted value
* @return long value in plain
* @throws SecurityException In case of decryption error
*/
public long decryptTypePreserving(long encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(encData).array();
byte[] data = decryptTypePreserving(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data);
return wrapped.getLong();
}
/**
* Encrypt a integer value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public int encryptTypePreserving(int data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(data).array();
byte[] encData = encryptTypePreserving(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData); // big-endian by default
return wrapped.getInt();
}
/**
* Decrypt an encryptyed integer value
*
* @param encData The encrypted value
* @return long value in plain
* @throws SecurityException In case of decryption error
*/
public int decryptTypePreserving(int encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(encData).array();
byte[] data = decryptTypePreserving(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data);
return wrapped.getInt();
}
/**
* Encrypt an integer value in order preserving form, encrypted value is of type long
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public long encryptOrderPreserving(int data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(data).array();
byte[] encData = encryptOPE(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData); // big-endian by default
return wrapped.getLong();
}
/**
* Decrypt an integer value encrypted with order preserving encryption
*
* @param encData The encrypted value
* @return Integer value in plain
* @throws SecurityException In case of decryption error
*/
public int decryptOrderPreserving(long encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(encData).array();
byte[] data = decryptOPE(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
return wrapped.getInt();
}
/**
* Encrypt a short value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public short encryptTypePreserving(short data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Short.SIZE / Byte.SIZE).putShort(data).array();
byte[] encData = encryptTypePreserving(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData); // big-endian by default
return wrapped.getShort();
}
/**
* Decrypt an encryptyed short value
*
* @param encData The encrypted value
* @return String value in plain
* @throws SecurityException In case of decryption error
*/
public short decryptTypePreserving(short encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Short.SIZE / Byte.SIZE).putShort(encData).array();
byte[] data = decryptTypePreserving(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data);
return wrapped.getShort();
}
/**
* Encrypt a short value in order preserving form, the return value is of type long
*
* @param data The value to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public long encryptOrderPreserving(short data) throws SecurityException
{
return encryptOrderPreserving((int) data);
}
/**
* Encrypt a float value
*
* @param data The value to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public float encryptTypePreserving(float data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Float.SIZE / Byte.SIZE).putFloat(data).array();
byte[] encData = encryptTypePreserving(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData);
return wrapped.getFloat();
}
/**
* Decrypt an encryptyed float value
*
* @param encData The encrypted value
* @return Float value in plain
* @throws SecurityException In case of decryption error
*/
public float decryptTypePreserving(float encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Float.SIZE / Byte.SIZE).putFloat(encData).array();
byte[] data = decryptTypePreserving(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data);
return wrapped.getFloat();
}
/**
* Encrypt a double value
*
* @param data The value to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public double encryptTypePreserving(double data) throws SecurityException
{
byte[] dataBytes = ByteBuffer.allocate(Double.SIZE / Byte.SIZE).putDouble(data).array();
byte[] encData = encryptTypePreserving(dataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(encData);
return wrapped.getDouble();
}
/**
* Decrypt an encryptyed double value
*
* @param encData The encrypted value
* @return Double value in plain
* @throws SecurityException In case of decryption error
*/
public double decryptTypePreserving(double encData) throws SecurityException
{
byte[] encDataBytes = ByteBuffer.allocate(Double.SIZE / Byte.SIZE).putDouble(encData).array();
byte[] data = decryptTypePreserving(encDataBytes);
ByteBuffer wrapped = ByteBuffer.wrap(data);
return wrapped.getDouble();
}
private static final int MS_PER_DAY = (1000 * 60 * 60 * 24);
/**
* Encrypt a Date value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.sql.Date encryptTypePreserving(java.sql.Date data) throws SecurityException
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(data);
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
utcCal.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
utcCal.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
utcCal.set(Calendar.MILLISECOND, 0);
utcCal.set(Calendar.SECOND, 0);
utcCal.set(Calendar.MINUTE, 0);
utcCal.set(Calendar.HOUR_OF_DAY, 0);
long dateAsLongUTC = utcCal.getTimeInMillis();
long d = dateAsLongUTC / MS_PER_DAY;
//long e = d * MS_PER_DAY;
byte[] dataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(d).array();
SDEUtils.reverseBytes(dataBytes);
dataBytes = Arrays.copyOf(dataBytes, 3); // we need only 3 bytes
byte[] encData = encryptTypePreserving(dataBytes, 20);
SDEUtils.reverseBytes(encData);
byte[] longData = new byte[8];
System.arraycopy(encData, 0, longData, 5, 3);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong() * MS_PER_DAY;
return new java.sql.Date(output);
}
/**
* Decrypt an encryptyed Date value
*
* @param encData The encrypted value
* @return Date value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Date decryptTypePreserving(java.sql.Date encData) throws SecurityException
{
long dateAsLong = encData.getTime();
long d = dateAsLong / MS_PER_DAY;
byte[] encDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(d).array();
SDEUtils.reverseBytes(encDataBytes);
encDataBytes = Arrays.copyOf(encDataBytes, 3); // we need only 3 bytes
byte[] data = decryptTypePreserving(encDataBytes, 20);
SDEUtils.reverseBytes(data);
byte[] longData = new byte[8];
System.arraycopy(data, 0, longData, 5, 3);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong();
Calendar localCal = Calendar.getInstance();
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.setTimeInMillis(output * MS_PER_DAY);
localCal.setTimeInMillis(0); // Epoch
localCal.set(Calendar.MILLISECOND, utcCal.get(Calendar.MILLISECOND));
localCal.set(Calendar.SECOND, utcCal.get(Calendar.SECOND));
localCal.set(Calendar.MINUTE, utcCal.get(Calendar.MINUTE));
localCal.set(Calendar.HOUR_OF_DAY, utcCal.get(Calendar.HOUR_OF_DAY));
localCal.set(Calendar.DAY_OF_MONTH, utcCal.get(Calendar.DAY_OF_MONTH));
localCal.set(Calendar.MONTH, utcCal.get(Calendar.MONTH));
localCal.set(Calendar.YEAR, utcCal.get(Calendar.YEAR));
return new java.sql.Date(localCal.getTimeInMillis());
}
/**
* Encrypt a Time value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.sql.Time encryptTypePreserving(java.sql.Time data) throws SecurityException
{
Calendar localCal = Calendar.getInstance();
localCal.setTime(data);
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.setTimeInMillis(0); // Epoch
utcCal.set(Calendar.MILLISECOND, 0);
utcCal.set(Calendar.SECOND, 0);
utcCal.set(Calendar.MINUTE, localCal.get(Calendar.MINUTE));
utcCal.set(Calendar.HOUR_OF_DAY, localCal.get(Calendar.HOUR_OF_DAY));
//long timeAsLong = Math.round(cal.getTimeInMillis()/10f);
long timeAsLong = utcCal.getTimeInMillis() / 1000 / 60;
byte[] dataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(timeAsLong).array();
SDEUtils.reverseBytes(dataBytes);
dataBytes = Arrays.copyOf(dataBytes, 2); // we need only 3 bytes
byte[] encData = encryptTypePreserving(dataBytes, 12);
SDEUtils.reverseBytes(encData);
byte[] longData = new byte[8];
System.arraycopy(encData, 0, longData, 6, 2);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong() * 1000;
return new java.sql.Time(output);
}
/**
* Decrypt an encryptyed Time value
*
* @param encData The encrypted value
* @return Time value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Time decryptTypePreserving(java.sql.Time encData) throws SecurityException
{
long timeAsLong = encData.getTime() / 1000;
byte[] encDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(timeAsLong).array();
byte[] data = new byte[Long.SIZE / Byte.SIZE];
SDEUtils.reverseBytes(encDataBytes);
encDataBytes = Arrays.copyOf(encDataBytes, 2); // we need only 3 bytes
data = decryptTypePreserving(encDataBytes, 12);
SDEUtils.reverseBytes(data);
byte[] longData = new byte[8];
System.arraycopy(data, 0, longData, 6, 2);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong();
//java.sql.Time time1 = new java.sql.Time(output * 100);
Calendar localCal = Calendar.getInstance();
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.setTimeInMillis(output * 1000 * 60);
localCal.setTimeInMillis(0); // Epoch
localCal.set(Calendar.MILLISECOND, 0);
localCal.set(Calendar.SECOND, 0);
localCal.set(Calendar.MINUTE, utcCal.get(Calendar.MINUTE));
localCal.set(Calendar.HOUR_OF_DAY, utcCal.get(Calendar.HOUR_OF_DAY));
java.sql.Time time = new java.sql.Time(localCal.getTime().getTime());
return time;
}
/**
* Encrypt a Timestamp value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.sql.Timestamp encryptTypePreserving(java.sql.Timestamp data) throws SecurityException
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(data);
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
utcCal.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
utcCal.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
utcCal.set(Calendar.MILLISECOND, calendar.get(Calendar.MILLISECOND));
utcCal.set(Calendar.SECOND, calendar.get(Calendar.SECOND));
utcCal.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE));
utcCal.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
long dateAsLongUTC = utcCal.getTimeInMillis();
byte[] dataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(dateAsLongUTC).array();
SDEUtils.reverseBytes(dataBytes);
dataBytes = Arrays.copyOf(dataBytes, 6);
byte[] encData = encryptTypePreserving(dataBytes, 46);
SDEUtils.reverseBytes(encData);
byte[] longData = new byte[8];
System.arraycopy(encData, 0, longData, 2, 6);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong();
java.sql.Timestamp date = new java.sql.Timestamp(output);
return date;
}
/**
* Decrypt an encryptyed Timestamp value
*
* @param encData The encrypted value
* @return Timestamp value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Timestamp decryptTypePreserving(java.sql.Timestamp encData) throws SecurityException
{
long dateAsLong = encData.getTime();
byte[] encDataBytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(dateAsLong).array();
SDEUtils.reverseBytes(encDataBytes);
encDataBytes = Arrays.copyOf(encDataBytes, 6);
byte[] data = decryptTypePreserving(encDataBytes, 46);
SDEUtils.reverseBytes(data);
byte[] longData = new byte[8];
System.arraycopy(data, 0, longData, 2, 6);
ByteBuffer wrapped = ByteBuffer.wrap(longData);
long output = wrapped.getLong();
Calendar localCal = Calendar.getInstance();
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
utcCal.setTimeInMillis(output);
localCal.setTimeInMillis(0); // Epoch
localCal.set(Calendar.MILLISECOND, utcCal.get(Calendar.MILLISECOND));
localCal.set(Calendar.SECOND, utcCal.get(Calendar.SECOND));
localCal.set(Calendar.MINUTE, utcCal.get(Calendar.MINUTE));
localCal.set(Calendar.HOUR_OF_DAY, utcCal.get(Calendar.HOUR_OF_DAY));
localCal.set(Calendar.DAY_OF_MONTH, utcCal.get(Calendar.DAY_OF_MONTH));
localCal.set(Calendar.MONTH, utcCal.get(Calendar.MONTH));
localCal.set(Calendar.YEAR, utcCal.get(Calendar.YEAR));
java.sql.Timestamp date = new java.sql.Timestamp(localCal.getTimeInMillis());
return date;
}
/**
* Encrypt a Timestamp value in order preserving form, encrypted value is of string type
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptOrderPreserving(java.sql.Timestamp data) throws SecurityException
{
long time = data.getTime();
int nanos = data.getNanos();
ByteBuffer encDataBytesBuffer = ByteBuffer.allocate(Long.SIZE / Byte.SIZE + Integer.SIZE / Byte.SIZE);
encDataBytesBuffer.putLong(0, time);
encDataBytesBuffer.putInt(Long.SIZE / Byte.SIZE, nanos);
byte[] dataBytes = encDataBytesBuffer.array();
byte[] encData = encryptOPE(dataBytes);
return SDEUtils.bytesToStringOP(encData);
}
/**
* Decrypt a Timestamp value encrypted with order preserving encryption
*
* @param encDataStr The encrypted value
* @return Timestamp value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Timestamp decryptOrderPreservingTS(String encDataStr) throws SecurityException
{
byte[] encData = SDEUtils.stringToBytesOP(encDataStr);
byte[] data = decryptOPE(encData);
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
long time = wrapped.getLong(0);
int nanos = wrapped.getInt(Long.SIZE / Byte.SIZE);
java.sql.Timestamp ts = new java.sql.Timestamp(time);
ts.setNanos(nanos);
return ts;
}
/**
* Encrypt a boolean value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public boolean encryptTypePreserving(boolean data) throws SecurityException
{
byte[] in = new byte[1];
in[0] = data ? (byte) 1 : (byte) 0;
return encryptTypePreserving(in, 1)[0] != 0;
}
/**
* Decrypt an encryptyed boolean value
*
* @param encData The encrypted value
* @return Boolean value in plain
* @throws SecurityException In case of decryption error
*/
public boolean decryptTypePreserving(boolean encData) throws SecurityException
{
byte[] in = new byte[1];
in[0] = encData ? (byte) 1 : (byte) 0;
return decryptTypePreserving(in, 1)[0] != 0;
}
/**
* Encrypt a Blob value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.sql.Blob encryptTypePreserving(java.sql.Blob data) throws SecurityException
{
try
{
byte[] enc = encryptTypePreserving(data.getBytes(1, (int) data.length()));
return new javax.sql.rowset.serial.SerialBlob(enc);
}
catch (SQLException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encryptyed Blob value
*
* @param encData The encrypted value
* @return Blob value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Blob decryptTypePreserving(java.sql.Blob encData) throws SecurityException
{
try
{
byte[] data = decryptTypePreserving(encData.getBytes(1, (int) encData.length()));
return new javax.sql.rowset.serial.SerialBlob(data);
}
catch (SQLException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a Clob value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.sql.Clob encryptTypePreserving(java.sql.Clob data) throws SecurityException
{
try
{
String enc = encryptTypePreserving(data.getSubString(1, (int) data.length()), true);
return new javax.sql.rowset.serial.SerialClob(enc.toCharArray());
}
catch (SQLException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encryptyed Clob value
*
* @param encData The encrypted value
* @return Clob value in plain
* @throws SecurityException In case of decryption error
*/
public java.sql.Clob decryptTypePreserving(java.sql.Clob encData) throws SecurityException
{
try
{
String data = decryptTypePreserving(encData.getSubString(1, (int) encData.length()), true);
return new javax.sql.rowset.serial.SerialClob(data.toCharArray());
}
catch (SQLException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a BigDecimal value
*
* @param data The data to encrypt
* @return Encrypted value
* @throws SecurityException In case of encryption error
*/
public java.math.BigDecimal encryptTypePreserving(java.math.BigDecimal data) throws SecurityException
{
try
{
int scale = data.scale();
BigInteger bi = data.unscaledValue();
boolean bNegative = bi.signum() == -1;
bi = bi.abs();
byte[] biBytes = bi.toByteArray();
int biBytesLength = biBytes.length;
if (biBytesLength > 12)
{
if ((biBytesLength == 13) && (biBytes[0] == 0))
{
// ok, ignore that
byte[] newBytes = new byte[12];
System.arraycopy(biBytes, 1, newBytes, 0, 12);
biBytes = newBytes;
}
else
{
throw new IllegalArgumentException("Value encryption is not supported");
}
}
else
{
biBytes = SDEUtils.addLeading(biBytes, (byte) 0, 12 - biBytesLength);
}
// if ((biBytesLength < 16) && ((biBytesLength % 2) != 0)) {
// if (biBytes[0] < 0) {
// biBytes = addLeading(biBytes, (byte) -1, 1);
// } else {
// biBytes = addLeading(biBytes, (byte) 0, 1);
// }
// }
byte[] enc = encryptTypePreserving(biBytes);
// enc = addLeading(enc, (byte) 1, 1); // make sure we wont have leading 0 on the byte array
enc = SDEUtils.addLeading(enc, (byte) 0, 1); // make it positive for sure
BigInteger encBi = new BigInteger(enc);
if (bNegative)
{
encBi = encBi.negate();
}
return new java.math.BigDecimal(encBi, scale);
}
catch (Exception e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encryptyed BigDecimal value
*
* @param encData The encrypted value
* @return BigDecimal value in plain
* @throws SecurityException In case of decryption error
*/
public java.math.BigDecimal decryptTypePreserving(java.math.BigDecimal encData) throws SecurityException
{
try
{
int scale = encData.scale();
BigInteger bi = encData.unscaledValue();
boolean bNegative = bi.signum() == -1;
bi = bi.abs();
byte[] biBytes = bi.toByteArray();
int biBytesLength = biBytes.length;
if (biBytesLength > 12)
{
if ((biBytesLength == 13) && (biBytes[0] == 0))
{
// ok, ignore that
byte[] newBytes = new byte[12];
System.arraycopy(biBytes, 1, newBytes, 0, 12);
biBytes = newBytes;
}
else
{
throw new IllegalArgumentException("Value encryption is not supported");
}
}
else
{
biBytes = SDEUtils.addLeading(biBytes, (byte) 0, 12 - biBytesLength);
}
// if (biBytes[0] != 1) {
// throw new IllegalArgumentException("Value was not decrypted with type preserving");
// }
// biBytes = removeLeading(biBytes, (byte) 1, true);
byte[] data = decryptTypePreserving(biBytes);
data = SDEUtils.addLeading(data, (byte) 0, 1); // make it positive for sure
BigInteger dataBi = new BigInteger(data);
if (bNegative)
{
dataBi = dataBi.negate();
}
// BigInteger dataBi = new BigInteger(data);
return new java.math.BigDecimal(dataBi, scale);
}
catch (Exception e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt an email address in format preserving form, the encrypted value is also a legitimate email address
*
* @param in Email address to encrypt
* @param maxLen Maximum size of all email addresses encrypted
* @return The encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptEMailAddress(String in, int maxLen) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_EMAIL_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.EMail.encrypt(rawKey, in, maxLen);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.encryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_EMAIL, null, maxLen, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encrypted email address, the encrypted value is also an email address
*
* @param in The encrypted value
* @return Original plain email address
* @throws SecurityException In case of decryption error
*/
public String decryptEMailAddress(String in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_EMAIL_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.EMail.decrypt(rawKey, in);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.decryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_EMAIL, null, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a credit card number in format preserving form, the encrypted value is also a legitimate
* credit card number
*
* @param in Credit card number to encrypt
* @return The encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptCreditCard(String in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_CREDIT_CARD_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.CreditCard.encrypt(rawKey, in, null);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.encryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_CREDIT_CARD, null, 0, inBuf);
if (outBuf == null) throw new SecurityException("encryptCreditCard failed");
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
public String encryptCreditCard(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_CREDIT_CARD_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.CreditCard.encrypt(rawKey, in, format);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.encryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_CREDIT_CARD, format.toCharArray(), 0, inBuf);
if (outBuf == null) throw new SecurityException("encryptCreditCard failed");
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt a credit card number, the encrypted value is also a credit card number
*
* @param in The encrypted value
* @return Original plain email address
* @throws SecurityException In case of decryption error
*/
public String decryptCreditCard(String in) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_CREDIT_CARD_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.CreditCard.decrypt(rawKey, in, null);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.decryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_CREDIT_CARD, null, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
public String decryptCreditCard(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_CREDIT_CARD_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.CreditCard.decrypt(rawKey, in, format);
}
try
{
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.decryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_CREDIT_CARD, format.toCharArray(), inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a US phone in format preserving form, the encrypted value is also a legitimate US phone number
*
* @param in Email address to encrypt
* @param format The output format, e.g. "###-###-####"
* @return The encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptUSPhone(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_US_PHONE_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.USPhone.encrypt(rawKey, in, format);
}
try
{
char[] formatChars = format == null ? null : format.toCharArray();
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.encryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_US_PHONE, formatChars, 0, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encrypted US phone number, the encrypted value is also a US phone number
*
* @param in The encrypted value
* @param format The output format, e.g. "###-###-####"
* @return Original plain US phone number
* @throws SecurityException In case of decryption error
*/
public String decryptUSPhone(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_US_PHONE_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.USPhone.decrypt(rawKey, in, format);
}
try
{
char[] formatChars = format == null ? null : format.toCharArray();
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.decryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_US_PHONE, formatChars, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Encrypt a SSN in format preserving form, the encrypted value is also a legitimate SSN
*
* @param in SSN to encrypt
* @param format The output format, e.g. "###-##-####"
* @return The encrypted value
* @throws SecurityException In case of encryption error
*/
public String encryptSSN(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_SSN_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.SSN.encrypt(rawKey, in, format);
}
try
{
char[] formatChars = format == null ? null : format.toCharArray();
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.encryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_SSN, formatChars, 0, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
/**
* Decrypt an encrypted SSN, the encrypted value is also SSN
*
* @param in The encrypted value
* @param format The output format, e.g. "###-##-####"
* @return Original plain SSN
* @throws SecurityException In case of decryption error
*/
public String decryptSSN(String in, String format) throws SecurityException
{
if (purpose != SDEKey.PURPOSE_SSN_ENC) throw new IllegalArgumentException("Invalid purpose");
if (rawKey!=null)
{
return FPE.SSN.decrypt(rawKey, in, format);
}
try
{
char[] formatChars = format == null ? null : format.toCharArray();
byte[] inBuf = in.getBytes("UTF-8");
byte[] outBuf = secretKey.decryptFPE(DYCK_FPE_PARAMS.DYCK_FPE_SSN, formatChars, inBuf);
return new String(outBuf, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new SecurityException(e);
}
catch (CKException e)
{
throw new SecurityException(e);
}
}
}