diff --git a/build.gradle b/build.gradle index f8bcd2c..45205ac 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } group = 'org.m2sec' -version = '2.2.8' +version = '2.2.9' def grpcVersion = '1.54.1' def protobufVersion = '3.24.0' def protocVersion = protobufVersion diff --git a/src/main/resources/examples/AesCbc.java b/src/main/resources/examples/AesCbc.java index 6cf66b2..aa08e44 100644 --- a/src/main/resources/examples/AesCbc.java +++ b/src/main/resources/examples/AesCbc.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class AesCbc{ +public class AesCbc { private Logger log; private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; diff --git a/src/main/resources/examples/AesEcb.java b/src/main/resources/examples/AesEcb.java index ff3e01e..08ec665 100644 --- a/src/main/resources/examples/AesEcb.java +++ b/src/main/resources/examples/AesEcb.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class AesEcb{ +public class AesEcb { private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; private static final byte[] secret = "32byteslongsecretkeyforaes256!aa".getBytes(); diff --git a/src/main/resources/examples/AesGcm.java b/src/main/resources/examples/AesGcm.java index 29c9e4a..88d31a5 100644 --- a/src/main/resources/examples/AesGcm.java +++ b/src/main/resources/examples/AesGcm.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class AesGcm{ +public class AesGcm { private static final String ALGORITHM = "AES/GCM/NoPadding"; private static final byte[] secret = "32byteslongsecretkeyforaes256!aa".getBytes(); diff --git a/src/main/resources/examples/AesRsa.java b/src/main/resources/examples/AesRsa.java index 372506c..432f83b 100644 --- a/src/main/resources/examples/AesRsa.java +++ b/src/main/resources/examples/AesRsa.java @@ -1,23 +1,41 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class AesRsa{ +public class AesRsa { private static final String SYMMERTIC_ALGORITHM = "AES/ECB/PKCS5Padding"; private static final byte[] aesSecret = "32byteslongsecretkeyforaes256!aa".getBytes(); private static final String ASYMMETRIC_ALGORITHM = "RSA"; - private static final String publicKey1Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR+Lhryv8CWezQIDAQAB"; - private static final String privateKey1Base64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj+0pUL8RhIJE"; - private static final String publicKey2Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfqYv278oDvreohZeR+UMiNSJC2FG4u8dSNC/hj88lw7eULQOiuUnsZ4eineeFOquXckjhkh1AJsd87+Nz1ZQB61dY3NmVR5Tk+2wH/kNdiVCoRrbULs29Tms17IyrZZU9WQFQbBxC/g6n5zwp6ST/siGRfHAwVVbq+iccQfdpwIDAQAB"; + private static final String publicKey1Base64 = + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM" + + "+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR" + + "+Lhryv8CWezQIDAQAB"; + private static final String privateKey1Base64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi" + + "/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg" + + "+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh" + + "+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2" + + "+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a" + + "/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7" + + "/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD" + + "/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp" + + "/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj" + + "+0pUL8RhIJE"; + private static final String publicKey2Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfqYv278oDvreohZeR" + + "+UMiNSJC2FG4u8dSNC/hj88lw7eULQOiuUnsZ4eineeFOquXckjhkh1AJsd87+Nz1ZQB61dY3NmVR5Tk+2wH" + + "/kNdiVCoRrbULs29Tms17IyrZZU9WQFQbBxC/g6n5zwp6ST/siGRfHAwVVbq+iccQfdpwIDAQAB"; private static final String privateKey2Base64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKt+pi/bvygO" + - "+t6iFl5H5QyI1IkLYUbi7x1I0L+GPzyXDt5QtA6K5Sexnh6Kd54U6q5dySOGSHUAmx3zv43PVlAHrV1jc2ZVHlOT7bAf+Q12JUKhGttQuzb1OazXsjKtllT1ZAVBsHEL+DqfnPCnpJP+yIZF8cDBVVur6JxxB92nAgMBAAECgYAghb2lcNKBGcooo2uDiLXe2SoZLT/O7iVzk8YGtEJUzr7imUJ0SZHoo639U7wYjhXtaFrHMmWWTr2cAggvMAVJi5fZYYJLbYdc8O5QCKi6PzV2J2NxYyuABL5yarvy4Ji0twnDjlqBYqrjOsxJbeMv58CHLKqduIZuxppGGOoRQQJBANTV3JEg6xJdPXsF9ztOf03BNkvpibuUSNbTssTdzEtLMQW7zd5y1qTCwUbf+e2UsRIYPn5DwOlTu8SaE97Zz8ECQQDORm7szA0WL1OTYob0U1NSSFDn8Jg7FyX5md6ndL3KNTKBDBfe3hNpauLi01lTMbO3MoriOWsFiN++6dZAdwdnAkEAq6PcwN1/Ncwj7Lae7yEa4SXUF9w6yx+GrlkDbmhAfOginLEcES0jlLPLEtFFySeEtUb//uu9A24XmzF2nN2jAQJABgL7fJ89ymW6s9LtR/WdugotgXT7ms1D6BBZ8ttuJJSEUkp975rdSfc5gY7TTZ9nM3GfppQx0El66994xQwzBQJAct1HPeCVROxyEHNwsiRH9wqR5P4B59Mo1714R7ozsdTpVx8FWmqi+OQIJt+IizYgRyQ09qORAFei9AHeQtxKiw=="; + "+t6iFl5H5QyI1IkLYUbi7x1I0L+GPzyXDt5QtA6K5Sexnh6Kd54U6q5dySOGSHUAmx3zv43PVlAHrV1jc2ZVHlOT7bAf" + + "+Q12JUKhGttQuzb1OazXsjKtllT1ZAVBsHEL+DqfnPCnpJP+yIZF8cDBVVur6JxxB92nAgMBAAECgYAghb2lcNKBGcooo2uDiLXe2SoZLT" + + "/O7iVzk8YGtEJUzr7imUJ0SZHoo639U7wYjhXtaFrHMmWWTr2cAggvMAVJi5fZYYJLbYdc8O5QCKi6PzV2J2NxYyuABL5yarvy4Ji0twnDjlqBYqrjOsxJbeMv58CHLKqduIZuxppGGOoRQQJBANTV3JEg6xJdPXsF9ztOf03BNkvpibuUSNbTssTdzEtLMQW7zd5y1qTCwUbf+e2UsRIYPn5DwOlTu8SaE97Zz8ECQQDORm7szA0WL1OTYob0U1NSSFDn8Jg7FyX5md6ndL3KNTKBDBfe3hNpauLi01lTMbO3MoriOWsFiN++6dZAdwdnAkEAq6PcwN1/Ncwj7Lae7yEa4SXUF9w6yx+GrlkDbmhAfOginLEcES0jlLPLEtFFySeEtUb//uu9A24XmzF2nN2jAQJABgL7fJ89ymW6s9LtR/WdugotgXT7ms1D6BBZ8ttuJJSEUkp975rdSfc5gY7TTZ9nM3GfppQx0El66994xQwzBQJAct1HPeCVROxyEHNwsiRH9wqR5P4B59Mo1714R7ozsdTpVx8FWmqi+OQIJt+IizYgRyQ09qORAFei9AHeQtxKiw=="; private static final byte[] publicKey1 = CodeUtil.b64decode(publicKey1Base64); private static final byte[] privateKey1 = CodeUtil.b64decode(privateKey1Base64); @@ -116,12 +134,13 @@ public Response hookResponseToClient(Response response) { } public byte[] asymmetricDecrypt(byte[] content, byte[] secret) { - return CryptoUtil.rsaDecrypt(content, secret); + return CryptoUtil.rsaDecrypt(ASYMMETRIC_ALGORITHM, content, secret); } public byte[] asymmetricEncrypt(byte[] content, byte[] secret) { - return CryptoUtil.rsaEncrypt(content, secret); + return CryptoUtil.rsaEncrypt(ASYMMETRIC_ALGORITHM, content, secret); } + public byte[] symmetricDecrypt(byte[] content, byte[] secret) { return CryptoUtil.aesDecrypt(SYMMERTIC_ALGORITHM, content, secret, null); } diff --git a/src/main/resources/examples/Des3Cbc.java b/src/main/resources/examples/Des3Cbc.java index f858649..eb18731 100644 --- a/src/main/resources/examples/Des3Cbc.java +++ b/src/main/resources/examples/Des3Cbc.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class Des3Cbc{ +public class Des3Cbc { private Logger log; private static final String ALGORITHM = "DESede/CBC/PKCS5Padding"; diff --git a/src/main/resources/examples/DesCbc.java b/src/main/resources/examples/DesCbc.java index 5f7f725..09275b8 100644 --- a/src/main/resources/examples/DesCbc.java +++ b/src/main/resources/examples/DesCbc.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class DesCbc{ +public class DesCbc { private Logger log; private static final String ALGORITHM = "DES/CBC/PKCS5Padding"; diff --git a/src/main/resources/examples/DynamicKey.java b/src/main/resources/examples/DynamicKey.java new file mode 100644 index 0000000..3b62042 --- /dev/null +++ b/src/main/resources/examples/DynamicKey.java @@ -0,0 +1,155 @@ +import org.m2sec.core.models.Request; +import org.m2sec.core.models.Response; +import org.m2sec.core.utils.CodeUtil; +import org.m2sec.core.utils.CryptoUtil; +import org.m2sec.core.utils.JsonUtil; +import org.slf4j.Logger; + +import java.util.HashMap; + +/** + * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md + * 按 Ctrl(control) + ` 可查看内置函数 + */ +public class DynamicKey { + + private static final String SYMMERTIC_ALGORITHM = "AES/ECB/PKCS5Padding"; + private static final String ASYMMETRIC_ALGORITHM = "RSA"; + private static final String publicKeyBase64 = + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM" + + "+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR" + + "+Lhryv8CWezQIDAQAB"; + private static final String privateKeyBase64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi" + + "/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg" + + "+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh" + + "+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2" + + "+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a" + + "/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7" + + "/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD" + + "/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp" + + "/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj" + + "+0pUL8RhIJE"; + + private static final byte[] publicKey = CodeUtil.b64decode(publicKeyBase64); + private static final byte[] privateKey = CodeUtil.b64decode(privateKeyBase64); + + private final ThreadLocal aesSecret = ThreadLocal.withInitial(() -> new byte[]{}); + + private static final String jsonKey1 = "data"; + private static final String jsonKey2 = "key"; + + private Logger log; + + public DynamicKey(Logger log) { + this.log = log; + } + + + /** + * HTTP请求从客户端到达Burp时被调用。在此处完成请求解密的代码就可以在Burp中看到明文的请求报文。 + * + * @param request Request 请求对象 + * @return 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + */ + public Request hookRequestToBurp(Request request) { + // 获取需要解密的数据 + byte[] encryptedData = getData(request.getContent()); + // 获取用来解密的密钥,该密钥已使用publicKey进行rsa加密 + byte[] encryptedKey = getKey(request.getContent()); + // 调用内置函数解密,拿到aes密钥 + byte[] key = asymmetricDecrypt(encryptedKey, privateKey); + aesSecret.set(key); + // 调用内置函数解密报文 + byte[] data = symmetricDecrypt(encryptedData, key); + // 更新body为已解密的数据 + request.setContent(data); + return request; + } + + /** + * HTTP请求从Burp将要发送到Server时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到Server。 + * + * @param request Request 请求对象 + * @return 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + */ + public Request hookRequestToServer(Request request) { + // 获取被解密的数据 + byte[] data = request.getContent(); + // 调用内置函数加密回去,这里使用设置的aesSecret进行加密 + byte[] encryptedData = symmetricEncrypt(data, aesSecret.get()); + // 调用内置函数加密aesSecret + byte[] encryptedKey = asymmetricEncrypt(aesSecret.get(), publicKey); + // 将已加密的数据转换为Server可识别的格式 + byte[] body = toData(encryptedData, encryptedKey); + // 更新body + request.setContent(body); + return request; + } + + /** + * HTTP请求从Server到达Burp时被调用。在此处完成响应解密的代码就可以在Burp中看到明文的响应报文。 + * + * @param response Response 响应对象 + * @return 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + */ + public Response hookResponseToBurp(Response response) { + // 获取需要解密的数据 + byte[] encryptedData = getData(response.getContent()); + // 调用内置函数解密 + byte[] data = symmetricDecrypt(encryptedData, aesSecret.get()); + // 更新body + response.setContent(data); + return response; + } + + /** + * HTTP请求从Burp将要发送到Client时被调用。在此处完成响应加密的代码就可以将加密后的响应报文返回给Client。 + * + * @param response Response 响应对象 + * @return 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + */ + public Response hookResponseToClient(Response response) { + // 获取被解密的数据 + byte[] data = response.getContent(); + // 调用内置函数加密回去 + byte[] encryptedData = symmetricEncrypt(data, aesSecret.get()); + // 更新body + // 将已加密的数据转换为Server可识别的格式 + byte[] body = toData(encryptedData, null); + // 更新body + response.setContent(body); + return response; + } + + public byte[] asymmetricDecrypt(byte[] content, byte[] secret) { + return CryptoUtil.rsaDecrypt(ASYMMETRIC_ALGORITHM, content, secret); + } + + public byte[] asymmetricEncrypt(byte[] content, byte[] secret) { + return CryptoUtil.rsaEncrypt(ASYMMETRIC_ALGORITHM, content, secret); + } + + public byte[] symmetricDecrypt(byte[] content, byte[] secret) { + return CryptoUtil.aesDecrypt(SYMMERTIC_ALGORITHM, content, secret, null); + } + + public byte[] symmetricEncrypt(byte[] content, byte[] secret) { + return CryptoUtil.aesEncrypt(SYMMERTIC_ALGORITHM, content, secret, null); + } + + private byte[] getData(byte[] content) { + return CodeUtil.b64decode((String) JsonUtil.jsonStrToMap(new String(content)).get(jsonKey1)); + } + + private byte[] getKey(byte[] content) { + return CodeUtil.b64decode((String) JsonUtil.jsonStrToMap(new String(content)).get(jsonKey2)); + } + + private byte[] toData(byte[] content, byte[] secret) { + HashMap jsonBody = new HashMap<>(); + jsonBody.put(jsonKey1, CodeUtil.b64encodeToString(content)); + if (secret != null) + jsonBody.put(jsonKey2, CodeUtil.b64encodeToString(secret)); + return JsonUtil.toJsonStr(jsonBody).getBytes(); + } +} diff --git a/src/main/resources/examples/Rsa.java b/src/main/resources/examples/Rsa.java index 37cd648..d787661 100644 --- a/src/main/resources/examples/Rsa.java +++ b/src/main/resources/examples/Rsa.java @@ -1,21 +1,39 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class Rsa{ +public class Rsa { private static final String ALGORITHM = "RSA"; - private static final String publicKey1Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR+Lhryv8CWezQIDAQAB"; - private static final String privateKey1Base64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj+0pUL8RhIJE"; - private static final String publicKey2Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfqYv278oDvreohZeR+UMiNSJC2FG4u8dSNC/hj88lw7eULQOiuUnsZ4eineeFOquXckjhkh1AJsd87+Nz1ZQB61dY3NmVR5Tk+2wH/kNdiVCoRrbULs29Tms17IyrZZU9WQFQbBxC/g6n5zwp6ST/siGRfHAwVVbq+iccQfdpwIDAQAB"; + private static final String publicKey1Base64 = + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM" + + "+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR" + + "+Lhryv8CWezQIDAQAB"; + private static final String privateKey1Base64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi" + + "/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg" + + "+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh" + + "+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2" + + "+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a" + + "/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7" + + "/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD" + + "/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp" + + "/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj" + + "+0pUL8RhIJE"; + private static final String publicKey2Base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfqYv278oDvreohZeR" + + "+UMiNSJC2FG4u8dSNC/hj88lw7eULQOiuUnsZ4eineeFOquXckjhkh1AJsd87+Nz1ZQB61dY3NmVR5Tk+2wH" + + "/kNdiVCoRrbULs29Tms17IyrZZU9WQFQbBxC/g6n5zwp6ST/siGRfHAwVVbq+iccQfdpwIDAQAB"; private static final String privateKey2Base64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKt+pi/bvygO" + - "+t6iFl5H5QyI1IkLYUbi7x1I0L+GPzyXDt5QtA6K5Sexnh6Kd54U6q5dySOGSHUAmx3zv43PVlAHrV1jc2ZVHlOT7bAf+Q12JUKhGttQuzb1OazXsjKtllT1ZAVBsHEL+DqfnPCnpJP+yIZF8cDBVVur6JxxB92nAgMBAAECgYAghb2lcNKBGcooo2uDiLXe2SoZLT/O7iVzk8YGtEJUzr7imUJ0SZHoo639U7wYjhXtaFrHMmWWTr2cAggvMAVJi5fZYYJLbYdc8O5QCKi6PzV2J2NxYyuABL5yarvy4Ji0twnDjlqBYqrjOsxJbeMv58CHLKqduIZuxppGGOoRQQJBANTV3JEg6xJdPXsF9ztOf03BNkvpibuUSNbTssTdzEtLMQW7zd5y1qTCwUbf+e2UsRIYPn5DwOlTu8SaE97Zz8ECQQDORm7szA0WL1OTYob0U1NSSFDn8Jg7FyX5md6ndL3KNTKBDBfe3hNpauLi01lTMbO3MoriOWsFiN++6dZAdwdnAkEAq6PcwN1/Ncwj7Lae7yEa4SXUF9w6yx+GrlkDbmhAfOginLEcES0jlLPLEtFFySeEtUb//uu9A24XmzF2nN2jAQJABgL7fJ89ymW6s9LtR/WdugotgXT7ms1D6BBZ8ttuJJSEUkp975rdSfc5gY7TTZ9nM3GfppQx0El66994xQwzBQJAct1HPeCVROxyEHNwsiRH9wqR5P4B59Mo1714R7ozsdTpVx8FWmqi+OQIJt+IizYgRyQ09qORAFei9AHeQtxKiw=="; + "+t6iFl5H5QyI1IkLYUbi7x1I0L+GPzyXDt5QtA6K5Sexnh6Kd54U6q5dySOGSHUAmx3zv43PVlAHrV1jc2ZVHlOT7bAf" + + "+Q12JUKhGttQuzb1OazXsjKtllT1ZAVBsHEL+DqfnPCnpJP+yIZF8cDBVVur6JxxB92nAgMBAAECgYAghb2lcNKBGcooo2uDiLXe2SoZLT" + + "/O7iVzk8YGtEJUzr7imUJ0SZHoo639U7wYjhXtaFrHMmWWTr2cAggvMAVJi5fZYYJLbYdc8O5QCKi6PzV2J2NxYyuABL5yarvy4Ji0twnDjlqBYqrjOsxJbeMv58CHLKqduIZuxppGGOoRQQJBANTV3JEg6xJdPXsF9ztOf03BNkvpibuUSNbTssTdzEtLMQW7zd5y1qTCwUbf+e2UsRIYPn5DwOlTu8SaE97Zz8ECQQDORm7szA0WL1OTYob0U1NSSFDn8Jg7FyX5md6ndL3KNTKBDBfe3hNpauLi01lTMbO3MoriOWsFiN++6dZAdwdnAkEAq6PcwN1/Ncwj7Lae7yEa4SXUF9w6yx+GrlkDbmhAfOginLEcES0jlLPLEtFFySeEtUb//uu9A24XmzF2nN2jAQJABgL7fJ89ymW6s9LtR/WdugotgXT7ms1D6BBZ8ttuJJSEUkp975rdSfc5gY7TTZ9nM3GfppQx0El66994xQwzBQJAct1HPeCVROxyEHNwsiRH9wqR5P4B59Mo1714R7ozsdTpVx8FWmqi+OQIJt+IizYgRyQ09qORAFei9AHeQtxKiw=="; private static final byte[] publicKey1 = CodeUtil.b64decode(publicKey1Base64); private static final byte[] privateKey1 = CodeUtil.b64decode(privateKey1Base64); @@ -101,11 +119,11 @@ public Response hookResponseToClient(Response response) { } public byte[] decrypt(byte[] content, byte[] privateKey) { - return CryptoUtil.rsaDecrypt(content, privateKey); + return CryptoUtil.rsaDecrypt(ALGORITHM, content, privateKey); } public byte[] encrypt(byte[] content, byte[] publicKey) { - return CryptoUtil.rsaEncrypt(content, publicKey); + return CryptoUtil.rsaEncrypt(ALGORITHM, content, publicKey); } private static byte[] getData(byte[] content) { diff --git a/src/main/resources/examples/Sm2.java b/src/main/resources/examples/Sm2.java index 6cc2afd..4ea0dfd 100644 --- a/src/main/resources/examples/Sm2.java +++ b/src/main/resources/examples/Sm2.java @@ -1,19 +1,27 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class Sm2{ - - private static final String publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ=="; - private static final String privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh"; - - private static final String publicKey2Base64="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; +public class Sm2 { + + private static final String MODE = "c1c2c3"; + private static final String publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh" + + "/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ=="; + private static final String privateKey1Base64 = + "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw" + + "/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc" + + "/EY40zjG8yUh"; + + private static final String publicKey2Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b" + + "/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; private static final String privateKey2Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgP8vW9tEh0dMP5gJNsol5Gyc6jvvgK1NRqOVg8VaLYVygCgYIKoEcz1UBgi2hRANCAAT/WSYiOU5+yob2E3hv87eGJIj3USuBUN6oH1g6AIWJSIXI+jfakIeHr3XMaegCPSX8/XfYLIuAF4fpNRr9OstS"; @@ -105,7 +113,7 @@ public Response hookResponseToClient(Response response) { * @return 解密结果 */ public byte[] decrypt(byte[] content, byte[] privateKey) { - return CryptoUtil.sm2Decrypt(content, privateKey); + return CryptoUtil.sm2Decrypt(MODE, content, privateKey); } /** @@ -113,7 +121,7 @@ public byte[] decrypt(byte[] content, byte[] privateKey) { * @return 加密结果 */ public byte[] encrypt(byte[] content, byte[] publicKey) { - return CryptoUtil.sm2Encrypt(content, publicKey); + return CryptoUtil.sm2Encrypt(MODE, content, publicKey); } private static byte[] getData(byte[] content) { diff --git a/src/main/resources/examples/Sm2Sm4.java b/src/main/resources/examples/Sm2Sm4.java index 2f55571..f23d5b1 100644 --- a/src/main/resources/examples/Sm2Sm4.java +++ b/src/main/resources/examples/Sm2Sm4.java @@ -1,25 +1,34 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class Sm2Sm4{ +public class Sm2Sm4 { private static final String SYMMERTIC_ALGORITHM = "SM4/ECB/PKCS5Padding"; private static final byte[] sm4Secret = "16byteslongkey12".getBytes(); private static final String ASYMMETRIC_ALGORITHM = "SM2"; - private static final String publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ=="; - private static final String privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh"; - private static final String publicKey2Base64="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; + private static final String SM2_MODE = "c1c2c3"; + private static final String publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh" + + "/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ=="; + private static final String privateKey1Base64 = + "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw" + + "/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc" + + "/EY40zjG8yUh"; + + private static final String publicKey2Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b" + + "/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; private static final String privateKey2Base64 = - "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgP8vW9tEh0dMP5gJNsol5Gyc6jvvgK1NRqOVg8VaLYVygCgYIKoEcz1UBgi2hRANCAAT/WSYiOU5+yob2E3hv87eGJIj3USuBUN6oH1g6AIWJSIXI+jfakIeHr3XMaegCPSX8/XfYLIuAF4fpNRr9OstS"; + "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgP8vW9tEh0dMP5gJNsol5Gyc6jvvgK1NRqOVg8VaLYVygCgYIKoEcz1UBgi2hRANCAAT/WSYiOU5+yob2E3hv87eGJIj3USuBUN6oH1g6AIWJSIXI+jfakIeHr3XMaegCPSX8/XfYLIuAF4fpNRr9OstS"; private static final byte[] publicKey1 = CodeUtil.b64decode(publicKey1Base64); private static final byte[] privateKey1 = CodeUtil.b64decode(privateKey1Base64); @@ -118,12 +127,13 @@ public Response hookResponseToClient(Response response) { } public byte[] asymmetricDecrypt(byte[] content, byte[] secret) { - return CryptoUtil.sm2Decrypt(content, secret); + return CryptoUtil.sm2Decrypt(SM2_MODE, content, secret); } public byte[] asymmetricEncrypt(byte[] content, byte[] secret) { - return CryptoUtil.sm2Encrypt(content, secret); + return CryptoUtil.sm2Encrypt(SM2_MODE, content, secret); } + public byte[] symmetricDecrypt(byte[] content, byte[] secret) { return CryptoUtil.sm4Decrypt(SYMMERTIC_ALGORITHM, content, secret, null); } diff --git a/src/main/resources/examples/Sm4.java b/src/main/resources/examples/Sm4.java index cc269e2..16bd45d 100644 --- a/src/main/resources/examples/Sm4.java +++ b/src/main/resources/examples/Sm4.java @@ -1,14 +1,16 @@ import org.m2sec.core.utils.*; import org.m2sec.core.models.*; + import java.util.HashMap; import java.util.Map; + import org.slf4j.Logger; /** * 内置示例,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md * 按 Ctrl(control) + ` 可查看内置函数 */ -public class Sm4{ +public class Sm4 { private Logger log; private static final String ALGORITHM = "SM4/CBC/PKCS5Padding"; diff --git a/src/main/resources/examples/aes_cbc.js b/src/main/resources/examples/aes_cbc.js index 84d4587..a202998 100644 --- a/src/main/resources/examples/aes_cbc.js +++ b/src/main/resources/examples/aes_cbc.js @@ -27,7 +27,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()) // 调用函数解密 @@ -43,7 +43,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.content // 调用函数加密回去 @@ -61,7 +61,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.content) // 调用函数解密 @@ -77,7 +77,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { data = response.content // 调用函数加密回去 encryptedData = encrypt(data) @@ -90,22 +90,22 @@ function hook_response_to_client(response){ } -function decrypt(content){ +function decrypt(content) { return CryptoUtil.aesDecrypt(ALGORITHM, content, secret, paramMap) } -function encrypt(content){ +function encrypt(content) { return CryptoUtil.aesEncrypt(ALGORITHM, content, secret, paramMap) } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -114,6 +114,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/aes_ecb.js b/src/main/resources/examples/aes_ecb.js index 6f7d605..c0a9714 100644 --- a/src/main/resources/examples/aes_ecb.js +++ b/src/main/resources/examples/aes_ecb.js @@ -23,7 +23,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 调用内置函数解密 @@ -39,7 +39,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去 @@ -57,7 +57,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 调用内置函数解密 @@ -73,7 +73,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用内置函数加密回去 @@ -94,12 +94,12 @@ function encrypt(content) { return CryptoUtil.aesEncrypt(ALGORITHM, content, secret, null); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -108,6 +108,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/aes_gcm.js b/src/main/resources/examples/aes_gcm.js index 4077a04..867437e 100644 --- a/src/main/resources/examples/aes_gcm.js +++ b/src/main/resources/examples/aes_gcm.js @@ -25,7 +25,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 调用内置函数解密 @@ -41,7 +41,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去 @@ -59,7 +59,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 调用内置函数解密 @@ -75,7 +75,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用内置函数加密回去 @@ -96,12 +96,12 @@ function encrypt(content) { return CryptoUtil.aesEncrypt(ALGORITHM, content, secret, paramMap); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -110,6 +110,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/aes_rsa.js b/src/main/resources/examples/aes_rsa.js index 1baefef..f502195 100644 --- a/src/main/resources/examples/aes_rsa.js +++ b/src/main/resources/examples/aes_rsa.js @@ -37,7 +37,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 获取用来解密的密钥,该密钥已使用publicKey1进行rsa加密 @@ -57,7 +57,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去,这里使用设置的aesSecret进行加密 @@ -77,7 +77,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 获取用来解密的密钥,该密钥已使用publicKey2进行rsa加密 @@ -97,7 +97,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用内置函数加密回去,这里使用设置的aesSecret进行加密 @@ -111,12 +111,12 @@ function hook_response_to_client(response){ return response; } -function asymmetric_decrypt(content, secret){ - return CryptoUtil.rsaDecrypt(content, secret); +function asymmetric_decrypt(content, secret) { + return CryptoUtil.rsaDecrypt(ASYMMETRIC_ALGORITHM, content, secret); } -function asymmetric_encrypt(content, secret){ - return CryptoUtil.rsaEncrypt(content, secret); +function asymmetric_encrypt(content, secret) { + return CryptoUtil.rsaEncrypt(ASYMMETRIC_ALGORITHM, content, secret); } function symmetric_decrypt(content, secret) { @@ -127,15 +127,16 @@ function symmetric_encrypt(content, secret) { return CryptoUtil.aesEncrypt(SYMMETRIC_ALGORITHM, content, secret, null); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey1)) } -function get_key(content){ + +function get_key(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey2)) } -function to_data(content, secret){ +function to_data(content, secret) { jsonBody = {} jsonBody[jsonKey1] = CodeUtil.b64encodeToString(content) jsonBody[jsonKey2] = CodeUtil.b64encodeToString(secret) @@ -145,6 +146,6 @@ function to_data(content, secret){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/aes_rsa.py b/src/main/resources/examples/aes_rsa.py index 863868a..f42af7f 100644 --- a/src/main/resources/examples/aes_rsa.py +++ b/src/main/resources/examples/aes_rsa.py @@ -13,7 +13,7 @@ """ -内置模版,需要自定义代码文件时查看该文档:https:#github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md +内置模版,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md 按 Ctrl(control) + ` 可查看内置函数 """ SYMMETRIC_ALGORITHM = "AES/ECB/PKCS5Padding" diff --git a/src/main/resources/examples/des3_cbc.js b/src/main/resources/examples/des3_cbc.js index cf262ed..7581e1d 100644 --- a/src/main/resources/examples/des3_cbc.js +++ b/src/main/resources/examples/des3_cbc.js @@ -27,7 +27,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()) // 调用函数解密 @@ -43,7 +43,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.content // 调用函数加密回去 @@ -61,7 +61,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.content) // 调用函数解密 @@ -77,7 +77,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { data = response.content // 调用函数加密回去 encryptedData = encrypt(data) @@ -90,22 +90,22 @@ function hook_response_to_client(response){ } -function decrypt(content){ +function decrypt(content) { return CryptoUtil.des3Decrypt(ALGORITHM, content, secret, paramMap) } -function encrypt(content){ +function encrypt(content) { return CryptoUtil.des3Encrypt(ALGORITHM, content, secret, paramMap) } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -114,6 +114,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/des_cbc.js b/src/main/resources/examples/des_cbc.js index 9b1f297..b36b6b6 100644 --- a/src/main/resources/examples/des_cbc.js +++ b/src/main/resources/examples/des_cbc.js @@ -27,7 +27,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()) // 调用函数解密 @@ -43,7 +43,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.content // 调用函数加密回去 @@ -61,7 +61,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.content) // 调用函数解密 @@ -77,7 +77,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { data = response.content // 调用函数加密回去 encryptedData = encrypt(data) @@ -90,22 +90,22 @@ function hook_response_to_client(response){ } -function decrypt(content){ +function decrypt(content) { return CryptoUtil.desDecrypt(ALGORITHM, content, secret, paramMap) } -function encrypt(content){ +function encrypt(content) { return CryptoUtil.desEncrypt(ALGORITHM, content, secret, paramMap) } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -114,6 +114,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/dynamic_key.js b/src/main/resources/examples/dynamic_key.js new file mode 100644 index 0000000..f932c04 --- /dev/null +++ b/src/main/resources/examples/dynamic_key.js @@ -0,0 +1,146 @@ +var CodeUtil = Java.type("org.m2sec.core.utils.CodeUtil") +var CryptoUtil = Java.type("org.m2sec.core.utils.CryptoUtil") +var HashUtil = Java.type("org.m2sec.core.utils.HashUtil") +var JsonUtil = Java.type("org.m2sec.core.utils.JsonUtil") +var MacUtil = Java.type("org.m2sec.core.utils.MacUtil") +var FactorUtil = Java.type("org.m2sec.core.utils.FactorUtil") +var Request = Java.type("org.m2sec.core.models.Request") +var Response = Java.type("org.m2sec.core.models.Response") +var String = Java.type("java.lang.String") +var ThreadLocal = Java.type("java.lang.ThreadLocal") + +SYMMETRIC_ALGORITHM = "AES/ECB/PKCS5Padding" +aesSecret = new ThreadLocal() +aesSecret.set("32byteslongsecretkeyforaes256!aa".getBytes()) + +ASYMMETRIC_ALGORITHM = "RSA" + +publicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR+Lhryv8CWezQIDAQAB"; +privateKeyBase64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj+0pUL8RhIJE"; + +publicKey = CodeUtil.b64decode(publicKeyBase64); +privateKey = CodeUtil.b64decode(privateKeyBase64); +jsonKey1 = "data" +jsonKey2 = "key" +log = void 0 + +/** + * 内置模版,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md + * 按 Ctrl(control) + ` 可查看内置函数 + */ + +/** + * HTTP请求从Burp将要发送到Server时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到Server。 + * @param {Request} request 请求对象 + * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + */ +function hook_request_to_burp(request) { + // 获取需要解密的数据 + encryptedData = get_data(request.getContent()); + // 获取用来解密的密钥,该密钥已使用publicKey进行rsa加密 + encryptedKey = get_key(request.getContent()) + // 调用内置函数解密,拿到aes密钥 + key = asymmetric_decrypt(encryptedKey, privateKey) + aesSecret.set(key) + // 调用内置函数解密报文 + data = symmetric_decrypt(encryptedData, key) + // 更新body为已解密的数据 + request.setContent(data); + return request; +} + + +/** + * HTTP请求从Burp将要发送到Server时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到Server。 + * @param {Request} request 请求对象 + * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + */ +function hook_request_to_server(request) { + // 获取被解密的数据 + data = request.getContent(); + // 调用内置函数加密回去,这里使用设置的aesSecret进行加密 + encryptedData = symmetric_encrypt(data, aesSecret.get()) + // 调用内置函数加密aesSecret + encryptedKey = asymmetric_encrypt(aesSecret.get(), publicKey) + // 将已加密的数据转换为Server可识别的格式 + body = to_data(encryptedData, encryptedKey) + // 更新body + request.setContent(body); + return request; +} + + +/** + * HTTP请求从Server到达Burp时被调用。在此处完成响应解密的代码就可以在Burp中看到明文的响应报文。 + * @param {Response} response 响应对象 + * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + */ +function hook_response_to_burp(response) { + // 获取需要解密的数据 + encryptedData = get_data(response.getContent()); + // 调用内置函数解密 + data = symmetric_decrypt(encryptedData, aesSecret.get()); + // 更新body + response.setContent(data); + return response; +} + + +/** + * HTTP请求从Burp将要发送到Client时被调用。在此处完成响应加密的代码就可以将加密后的响应报文返回给Client。 + * @param {Response} response 响应对象 + * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + */ +function hook_response_to_client(response) { + // 获取被解密的数据 + data = response.getContent(); + // 调用内置函数加密回去 + encryptedData = symmetric_encrypt(data, aesSecret.get()); + // 更新body + // 将已加密的数据转换为Server可识别的格式 + body = to_data(encryptedData, null); + // 更新body + response.setContent(body); + return response; +} + +function asymmetric_decrypt(content, secret) { + return CryptoUtil.rsaDecrypt(ASYMMETRIC_ALGORITHM, content, secret); +} + +function asymmetric_encrypt(content, secret) { + return CryptoUtil.rsaEncrypt(ASYMMETRIC_ALGORITHM, content, secret); +} + +function symmetric_decrypt(content, secret) { + return CryptoUtil.aesDecrypt(SYMMETRIC_ALGORITHM, content, secret, null); +} + +function symmetric_encrypt(content, secret) { + return CryptoUtil.aesEncrypt(SYMMETRIC_ALGORITHM, content, secret, null); +} + +function get_data(content) { + return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey1)) +} + +function get_key(content) { + return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey2)) +} + + +function to_data(content, secret) { + jsonBody = {} + jsonBody[jsonKey1] = CodeUtil.b64encodeToString(content) + if (secret != null) { + jsonBody[jsonKey2] = CodeUtil.b64encodeToString(secret) + } + return JsonUtil.toJsonStr(jsonBody).getBytes() +} + +/** + * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 + */ +function set_log(log1) { + log = log1 +} \ No newline at end of file diff --git a/src/main/resources/examples/dynamic_key.py b/src/main/resources/examples/dynamic_key.py new file mode 100644 index 0000000..2611193 --- /dev/null +++ b/src/main/resources/examples/dynamic_key.py @@ -0,0 +1,144 @@ +import json +import base64 +from org.m2sec.core.utils import ( + CodeUtil, + CryptoUtil, + HashUtil, + JsonUtil, + MacUtil, + FactorUtil, +) +from org.m2sec.core.models import Request, Response +from java.lang import String, ThreadLocal + +""" +内置模版,需要自定义代码文件时查看该文档:https://github.com/outlaws-bai/Galaxy/blob/main/docs/Custom.md +按 Ctrl(control) + ` 可查看内置函数 +""" +SYMMETRIC_ALGORITHM = "AES/ECB/PKCS5Padding" +aesSecret = ThreadLocal() +aesSecret.set("32byteslongsecretkeyforaes256!aa".encode()) +ASYMMETRIC_ALGORITHM = "RSA" +publicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JoQAWLsovzHjaUMZg2lwO4LCuP97mitUc4chqRlQD3NgyCWLqEnYyM+OJ7i6cyMuWLwGtMi29DoKLjpE/xRZR0OUk46PDCAtyDgIyejK7c7KlZTbiqb4PtiJNLZgg0UP62kLMycnpY/wg/R2G9g+7MiJWUV5SR+Lhryv8CWezQIDAQAB" +privateKeyBase64 = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALsmhABYuyi/MeNpQxmDaXA7gsK4/3uaK1RzhyGpGVAPc2DIJYuoSdjIz44nuLpzIy5YvAa0yLb0OgouOkT/FFlHQ5STjo8MIC3IOAjJ6MrtzsqVlNuKpvg+2Ik0tmCDRQ/raQszJyelj/CD9HYb2D7syIlZRXlJH4uGvK/wJZ7NAgMBAAECgYAhgbhRbZF4rp6Kdh6e00HN58G2BjQrl4MZeCOh+aoABPwlwD/EnMk36GAMtfzjWNjcI+PqGXT0GI7JotQo5ThpoweXX/uoeGOW+UkYLA6a67lmxfoZsDtY2+jnaWIs2c7Itz3ClRxo4tYwCoPNjtaBpMfPgZaYg2QN8/wLQPI66wJBAM0xpjb2OlLDs75lVxbm6v6Dx3YBS20GSqJqvf+14a/k7mrZ3PmAHOfqTqKOwbVQJmLbeOpU+sUBpeLpILKOCLcCQQDpfSsDhdosC6qTL9XnF2jS49iws2RBKw5YjDkClwA6VMNj5uzL1Rl7/AimLRMnB4BwrD95ksuOJsqNXW6wRGibAkAkk28PaQCodB38GFBX0r2ctJy/Wie5vV9caC6KAD/EfMhK357WEpIUfN2beFrrGOhewsRg8NjqeQq60dd0PIEtAkBYAm03O7n8Bj26kzpejA1gCLBCEqyEf/U9XUWT+1UDp7Wqr32sa1vaxyp/cNgaSxKX5eVbLwD5SRfqZ0B0wqRnAkATpUNiCqjQVS+OI5dwjoI1Rx3oI8pyKWOg3+QIHIRgL3pc8HLdZ2BkX4Vf6ANb4+noQnD/di1Mj+0pUL8RhIJE" + +publicKey = CodeUtil.b64decode(publicKeyBase64) +privateKey = CodeUtil.b64decode(privateKeyBase64) +jsonKey1 = "data" +jsonKey2 = "key" +log = None + +def hook_request_to_burp(request): + """HTTP请求从客户端到达Burp时被调用。在此处完成请求解密的代码就可以在Burp中看到明文的请求报文。 + + Args: + request (Request): 请求对象 + + Returns: + Request: 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + """ + # 获取需要解密的数据 + encryptedData = get_data(request.getContent()) + # 获取用来解密的密钥,该密钥已使用publicKey进行rsa加密 + encryptedKey = get_key(request.getContent()) + # 调用内置函数解密,拿到aes密钥 + key = asymmetric_decrypt(encryptedKey, privateKey) + aesSecret.set(key) + # 调用内置函数解密报文 + data = symmetric_decrypt(encryptedData, key) + # 更新body为已解密的数据 + request.setContent(data) + return request + + +def hook_request_to_server(request): + """HTTP请求从Burp将要发送到Server时被调用。在此处完成请求加密的代码就可以将加密后的请求报文发送到Server。 + + Args: + request (Request): 请求对象 + + Returns: + Request: 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 + """ + # 获取被解密的数据 + data = request.getContent() + # 调用内置函数加密回去,这里使用设置的aesSecret进行加密 + encryptedData = symmetric_encrypt(data, aesSecret.get()) + # 调用内置函数加密aesSecret + encryptedKey = asymmetric_encrypt(aesSecret.get(), publicKey) + # 将已加密的数据转换为Server可识别的格式 + body = to_data(encryptedData, encryptedKey) + # 更新body + request.setContent(body) + return request + + +def hook_response_to_burp(response): + """HTTP请求从Server到达Burp时被调用。在此处完成响应解密的代码就可以在Burp中看到明文的响应报文。 + + Args: + response (Response): 响应对象 + + Returns: + Response: 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + """ + # 获取需要解密的数据 + encryptedData = get_data(response.getContent()) + # 调用内置函数解密 + data = symmetric_decrypt(encryptedData, aesSecret.get()) + # 更新body + response.setContent(data) + return response + +def hook_response_to_client(response): + """HTTP请求从Burp将要发送到Client时被调用。在此处完成响应加密的代码就可以将加密后的响应报文返回给Client。 + + Args: + response (Response): 响应对象 + + Returns: + Response: 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 + """ + # 获取被解密的数据 + data = response.getContent() + # 调用内置函数加密回去 + encryptedData = symmetric_encrypt(data, aesSecret.get()) + # 更新body + # 将已加密的数据转换为Server可识别的格式 + body = to_data(encryptedData, None) + # 更新body + response.setContent(body) + return response + +def asymmetric_decrypt(content, secret): + return CryptoUtil.rsaDecrypt(ASYMMETRIC_ALGORITHM, content, secret) + +def asymmetric_encrypt(content, secret): + return CryptoUtil.rsaEncrypt(ASYMMETRIC_ALGORITHM, content, secret) + +def symmetric_decrypt(content, secret): + return CryptoUtil.aesDecrypt(SYMMETRIC_ALGORITHM, content, secret, None) + +def symmetric_encrypt(content, secret): + return CryptoUtil.aesEncrypt(SYMMETRIC_ALGORITHM, content, secret, None) + +def get_data(content): + return CodeUtil.b64decode(JsonUtil.jsonStrToMap(String(content)).get(jsonKey1)) + +def get_key(content): + return CodeUtil.b64decode(JsonUtil.jsonStrToMap(String(content)).get(jsonKey2)) + + +def to_data(content, secret): + jsonBody = {} + jsonBody[jsonKey1] = CodeUtil.b64encodeToString(content) + if secret is not None: + jsonBody[jsonKey2] = CodeUtil.b64encodeToString(secret) + return JsonUtil.toJsonStr(jsonBody).encode() + +def set_log(log1): + """程序在最开始会自动调用该函数,在上方函数可以放心使用log对象""" + global log + log = log1 + + diff --git a/src/main/resources/examples/rsa.js b/src/main/resources/examples/rsa.js index be5b181..98b65c4 100644 --- a/src/main/resources/examples/rsa.js +++ b/src/main/resources/examples/rsa.js @@ -33,7 +33,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 调用内置函数解密 @@ -49,7 +49,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去 @@ -67,7 +67,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 调用内置函数解密 @@ -83,7 +83,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用内置函数加密回去 @@ -97,19 +97,19 @@ function hook_response_to_client(response){ } function decrypt(content, secret) { - return CryptoUtil.rsaDecrypt(content, secret); + return CryptoUtil.rsaDecrypt(ALGORITHM, content, secret); } function encrypt(content, secret) { - return CryptoUtil.rsaEncrypt(content, secret); + return CryptoUtil.rsaEncrypt(ALGORITHM, content, secret); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -118,6 +118,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/rsa.py b/src/main/resources/examples/rsa.py index 6937f39..e7a80cf 100644 --- a/src/main/resources/examples/rsa.py +++ b/src/main/resources/examples/rsa.py @@ -106,10 +106,10 @@ def hook_response_to_client(response): return response def decrypt(content, secret): - return CryptoUtil.rsaDecrypt(content, secret) + return CryptoUtil.rsaDecrypt(ALGORITHM, content, secret) def encrypt(content, secret): - return CryptoUtil.rsaEncrypt(content, secret) + return CryptoUtil.rsaEncrypt(ALGORITHM, content, secret) def get_data(content): return CodeUtil.b64decode(JsonUtil.jsonStrToMap(String(content)).get(jsonKey)) diff --git a/src/main/resources/examples/sm2.js b/src/main/resources/examples/sm2.js index 1cf649a..d77ddd8 100644 --- a/src/main/resources/examples/sm2.js +++ b/src/main/resources/examples/sm2.js @@ -9,10 +9,11 @@ var Response = Java.type("org.m2sec.core.models.Response") var String = Java.type("java.lang.String") ALGORITHM = "SM2" +MODE = "c1c2c3" publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ=="; privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh"; -publicKey2Base64="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; +publicKey2Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg=="; privateKey2Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgP8vW9tEh0dMP5gJNsol5Gyc6jvvgK1NRqOVg8VaLYVygCgYIKoEcz1UBgi2hRANCAAT/WSYiOU5+yob2E3hv87eGJIj3USuBUN6oH1g6AIWJSIXI+jfakIeHr3XMaegCPSX8/XfYLIuAF4fpNRr9OstS"; @@ -34,7 +35,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 调用内置函数解密 @@ -50,7 +51,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去 @@ -68,7 +69,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 调用内置函数解密 @@ -84,7 +85,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 adata = response.getContent(); // 调用内置函数加密回去 @@ -98,19 +99,19 @@ function hook_response_to_client(response){ } function decrypt(content, secret) { - return CryptoUtil.sm2Decrypt(content, secret); + return CryptoUtil.sm2Decrypt(MODE, content, secret); } function encrypt(content, secret) { - return CryptoUtil.sm2Encrypt(content, secret); + return CryptoUtil.sm2Encrypt(MODE, content, secret); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -119,6 +120,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/sm2.py b/src/main/resources/examples/sm2.py index 56796ba..895e15e 100644 --- a/src/main/resources/examples/sm2.py +++ b/src/main/resources/examples/sm2.py @@ -18,6 +18,7 @@ """ ALGORITHM = "SM2" +MODE = "c1c2c3" publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ==" privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh" @@ -109,10 +110,10 @@ def hook_response_to_client(response): return response def decrypt(content, secret): - return CryptoUtil.sm2Decrypt(content, secret) + return CryptoUtil.sm2Decrypt(MODE, content, secret) def encrypt(content, secret): - return CryptoUtil.sm2Encrypt(content, secret) + return CryptoUtil.sm2Encrypt(MODE, content, secret) def get_data(content): return CodeUtil.b64decode(JsonUtil.jsonStrToMap(String(content)).get(jsonKey)) diff --git a/src/main/resources/examples/sm2_sm4.js b/src/main/resources/examples/sm2_sm4.js index d858a5a..83f4511 100644 --- a/src/main/resources/examples/sm2_sm4.js +++ b/src/main/resources/examples/sm2_sm4.js @@ -12,11 +12,11 @@ SYMMETRIC_ALGORITHM = "SM4/ECB/PKCS5Padding" sm4Secret = "16byteslongkey12".getBytes() ASYMMETRIC_ALGORITHM = "SM2" - +SM2_MODE = "c1c2c3" publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ==" privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh" -publicKey2Base64="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg==" +publicKey2Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/1kmIjlOfsqG9hN4b/O3hiSI91ErgVDeqB9YOgCFiUiFyPo32pCHh691zGnoAj0l/P132CyLgBeH6TUa/TrLUg==" privateKey2Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgP8vW9tEh0dMP5gJNsol5Gyc6jvvgK1NRqOVg8VaLYVygCgYIKoEcz1UBgi2hRANCAAT/WSYiOU5+yob2E3hv87eGJIj3USuBUN6oH1g6AIWJSIXI+jfakIeHr3XMaegCPSX8/XfYLIuAF4fpNRr9OstS" publicKey1 = CodeUtil.b64decode(publicKey1Base64) @@ -38,7 +38,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 获取用来解密的密钥,该密钥已使用publicKey1进行sm2加密 @@ -58,7 +58,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用内置函数加密回去,这里使用设置的sm4Secret进行加密 @@ -78,7 +78,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 获取用来解密的密钥,该密钥已使用publicKey2进行sm2加密 @@ -98,7 +98,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用内置函数加密回去,这里使用设置的sm4Secret进行加密 @@ -112,12 +112,12 @@ function hook_response_to_client(response){ return response; } -function asymmetric_decrypt(content, secret){ - return CryptoUtil.sm2Decrypt(content, secret); +function asymmetric_decrypt(content, secret) { + return CryptoUtil.sm2Decrypt(SM2_MODE, content, secret); } -function asymmetric_encrypt(content, secret){ - return CryptoUtil.sm2Encrypt(content, secret); +function asymmetric_encrypt(content, secret) { + return CryptoUtil.sm2Encrypt(SM2_MODE, content, secret); } function symmetric_decrypt(content, secret) { @@ -128,15 +128,16 @@ function symmetric_encrypt(content, secret) { return CryptoUtil.sm4Encrypt(SYMMETRIC_ALGORITHM, content, secret, null); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey1)) } -function get_key(content){ + +function get_key(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey2)) } -function to_data(content, secret){ +function to_data(content, secret) { jsonBody = {} jsonBody[jsonKey1] = CodeUtil.b64encodeToString(content) jsonBody[jsonKey2] = CodeUtil.b64encodeToString(secret) @@ -146,6 +147,6 @@ function to_data(content, secret){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/main/resources/examples/sm2_sm4.py b/src/main/resources/examples/sm2_sm4.py index 99dbfb8..3e88089 100644 --- a/src/main/resources/examples/sm2_sm4.py +++ b/src/main/resources/examples/sm2_sm4.py @@ -19,6 +19,7 @@ SYMMETRIC_ALGORITHM = "SM4/ECB/PKCS5Padding" sm4Secret = b"16byteslongkey12" ASYMMETRIC_ALGORITHM = "SM2" +SM2_MODE = "c1c2c3" publicKey1Base64 = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBv9Z+xbmSOH3W/V9UEpU1yUiJKNGh/I8EiENTPYxX3GujsZyKhuEUzxloKCATcNaKWi7w/yK3PxGONM4xvMlIQ==" privateKey1Base64 = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgWmIprZ5a6TsqRUgy32J+F22AYIKl+14P4qlw/LPPCcagCgYIKoEcz1UBgi2hRANCAAQG/1n7FuZI4fdb9X1QSlTXJSIko0aH8jwSIQ1M9jFfca6OxnIqG4RTPGWgoIBNw1opaLvD/Irc/EY40zjG8yUh" @@ -122,10 +123,10 @@ def hook_response_to_client(response): return response def asymmetric_decrypt(content, secret): - return CryptoUtil.sm2Decrypt(content, secret) + return CryptoUtil.sm2Decrypt(SM2_MODE, content, secret) def asymmetric_encrypt(content, secret): - return CryptoUtil.sm2Encrypt(content, secret) + return CryptoUtil.sm2Encrypt(SM2_MODE, content, secret) def symmetric_decrypt(content, secret): return CryptoUtil.sm4Decrypt(SYMMETRIC_ALGORITHM, content, secret, None) diff --git a/src/main/resources/examples/sm4.js b/src/main/resources/examples/sm4.js index a3427da..b2223d9 100644 --- a/src/main/resources/examples/sm4.js +++ b/src/main/resources/examples/sm4.js @@ -25,7 +25,7 @@ log = void 0 * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_burp(request){ +function hook_request_to_burp(request) { // 获取需要解密的数据 encryptedData = get_data(request.getContent()); // 调用函数解密 @@ -41,7 +41,7 @@ function hook_request_to_burp(request){ * @param {Request} request 请求对象 * @returns 经过处理后的request对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_request_to_server(request){ +function hook_request_to_server(request) { // 获取被解密的数据 data = request.getContent(); // 调用函数加密回去 @@ -59,7 +59,7 @@ function hook_request_to_server(request){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_burp(response){ +function hook_response_to_burp(response) { // 获取需要解密的数据 encryptedData = get_data(response.getContent()); // 调用函数解密 @@ -75,7 +75,7 @@ function hook_response_to_burp(response){ * @param {Response} response 响应对象 * @returns 经过处理后的response对象,返回null代表从当前节点开始流量不再需要处理 */ -function hook_response_to_client(response){ +function hook_response_to_client(response) { // 获取被解密的数据 data = response.getContent(); // 调用函数加密回去 @@ -96,12 +96,12 @@ function encrypt(content) { return CryptoUtil.sm4Encrypt(ALGORITHM, content, secret, paramMap); } -function get_data(content){ +function get_data(content) { return CodeUtil.b64decode(JsonUtil.jsonStrToMap(new String(content)).get(jsonKey)) } -function to_data(content){ +function to_data(content) { jsonBody = {} jsonBody[jsonKey] = CodeUtil.b64encodeToString(content) return JsonUtil.toJsonStr(jsonBody).getBytes() @@ -110,6 +110,6 @@ function to_data(content){ /** * 程序在最开始会自动调用该函数,在上方函数可以放心使用log对象 */ -function set_log(log1){ +function set_log(log1) { log = log1 } \ No newline at end of file diff --git a/src/test/java/org/m2sec/core/httphook/HttpHookCodeTest.java b/src/test/java/org/m2sec/core/httphook/HttpHookCodeTest.java index 12e2215..4c5f59a 100644 --- a/src/test/java/org/m2sec/core/httphook/HttpHookCodeTest.java +++ b/src/test/java/org/m2sec/core/httphook/HttpHookCodeTest.java @@ -32,7 +32,7 @@ public static void setRootLoggerLevel() { @Test public void testOneCodeHooker() { - testCodeHooker(examplesFilePath + File.separator + "Sm2.java"); + testCodeHooker(examplesFilePath + File.separator + "dynamic_key.js"); }