package gw.plugin.encryption.impl; uses gw.plugin.InitializablePlugin uses gw.plugin.PluginParameter uses gw.plugin.util.IEncryption uses gw.util.StreamUtil uses javax.crypto.Cipher uses javax.crypto.SecretKeyFactory uses javax.crypto.spec.PBEKeySpec uses javax.crypto.spec.PBEParameterSpec /** * This class provides a configurable encryption plugin using javax.crypto.spec.PBE... classes. * * parameter "identifier" - the encryption id for this specific implementationation * parameter "key" - a long key phrase for the password phrase * parameter "salt" - this is typically a block length of byte * parameter "iterationCount" - how many times to iterate over the key phrase to produce the key * parameter "PBE.digest" - the digets * parameter "PBE.encryption" - the algorythm * see https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory; */ @ReadOnly @PluginParameter(:name="identifier", :type=String) @PluginParameter(:name="key", :type=String) @PluginParameter(:name="salt", :type=String) @PluginParameter(:name="iterationCount", :type=Integer) @PluginParameter(:name="PBE.digest", :type=String) @PluginParameter(:name="PBE.encryption", :type=String) class PBEEncryptionPlugin implements IEncryption, InitializablePlugin { public final static var ID_PARAM : String = "identifier"; public final static var KEY_PARAM : String = "key"; public final static var SALT_PARAM : String = "salt"; public final static var ITERATION_PARAM : String = "iterationCount"; public final static var PBE_DIGEST_PARAM : String = "PBE.digest"; public final static var PBE_ENCRYPTION_PARAM : String = "PBE.encryption"; var _ecipher : Cipher; var _dcipher : Cipher; var _identifier : String; override property set Parameters(params : Map) { _identifier = params.get(ID_PARAM) as String; if (_identifier == null) { throw new IllegalArgumentException("identifier is required for IEncryption plugin") } var keyPhrase = getParameter(params, KEY_PARAM, "No password supplied by configuration").toCharArray() var iterationCount = getIntegerParameter(params, ITERATION_PARAM, 19); var salt = StreamUtil.toBytes(getParameter(params, SALT_PARAM, "\u0070\u006B\u0058\u0032\u0056\u0035\u0073\u0003")) var pbeDigest = getParameter(params, PBE_DIGEST_PARAM, "SHA1"); var pbeEncryption = getParameter(params, PBE_ENCRYPTION_PARAM, "DESede"); var keySpec = new PBEKeySpec(keyPhrase, salt, iterationCount); var key = SecretKeyFactory.getInstance("PBEWith" + pbeDigest + "And" + pbeEncryption).generateSecret(keySpec); _ecipher = Cipher.getInstance(key.getAlgorithm()); _dcipher = Cipher.getInstance(key.getAlgorithm()); var paramSpec = new PBEParameterSpec(salt, iterationCount); _ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); _dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); } override function getEncryptedLength(size:int) : int { var rtn = encrypt(new String(new char[size])) return rtn.length() } override property get EncryptionIdentifier() : String { return _identifier } override function encrypt(str : String) : String { var utf8 = StreamUtil.toBytes(str); var enc = _ecipher.doFinal(utf8); return StreamUtil.toString(Base64.getEncoder().encode(enc)); } override function decrypt(str : String) : String { var dec = Base64.getDecoder().decode(str); var utf8 = _dcipher.doFinal(dec); return StreamUtil.toString(utf8); } private function getParameter(params : Map, name : String, defaultValue : String) : String { var work = params.get(name) as String; if (work != null && work.length > 0) { return work; } return defaultValue; } private function getIntegerParameter(params : Map, name : String, defaultValue : int) : int { var work = params.get(name) as String; if (work != null && work.length > 0) { var workInt = Integer.parseInt(work); if (workInt > 0) { return workInt; } } return defaultValue; } }