diff --git a/src/main/java/org/m2sec/core/common/XXTEATools.java b/src/main/java/org/m2sec/core/common/XXTEATools.java new file mode 100644 index 0000000..b7cc67e --- /dev/null +++ b/src/main/java/org/m2sec/core/common/XXTEATools.java @@ -0,0 +1,117 @@ +package org.m2sec.core.common; + +/** + * @author: outlaws-bai + * @date: 2024/8/4 16:46 + * @description: + */ + +public class XXTEATools { + private static final int DELTA = 0x9E3779B9; + + private static int MX(int sum, int y, int z, int p, int e, int[] k) { + return (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z); + } + + + public static byte[] encrypt(byte[] data, byte[] key) { + assert key.length == 16; + if (data.length == 0) { + return data; + } + return toByteArray( + encrypt(toIntArray(data, true), toIntArray(key, false)), false); + } + + public static byte[] decrypt(byte[] data, byte[] key) { + assert key.length == 16; + if (data.length == 0) { + return data; + } + return toByteArray( + decrypt(toIntArray(data, false), toIntArray(key, false)), true); + } + + private static int[] encrypt(int[] v, int[] k) { + int n = v.length - 1; + + if (n < 1) { + return v; + } + int p, q = 6 + 52 / (n + 1); + int z = v[n], y, sum = 0, e; + + while (q-- > 0) { + sum = sum + DELTA; + e = sum >>> 2 & 3; + for (p = 0; p < n; p++) { + y = v[p + 1]; + z = v[p] += MX(sum, y, z, p, e, k); + } + y = v[0]; + z = v[n] += MX(sum, y, z, p, e, k); + } + return v; + } + + private static int[] decrypt(int[] v, int[] k) { + int n = v.length - 1; + + if (n < 1) { + return v; + } + int p, q = 6 + 52 / (n + 1); + int z, y = v[0], sum = q * DELTA, e; + + while (sum != 0) { + e = sum >>> 2 & 3; + for (p = n; p > 0; p--) { + z = v[p - 1]; + y = v[p] -= MX(sum, y, z, p, e, k); + } + z = v[n]; + y = v[0] -= MX(sum, y, z, p, e, k); + sum = sum - DELTA; + } + return v; + } + + + private static int[] toIntArray(byte[] data, boolean includeLength) { + int n = (((data.length & 3) == 0) + ? (data.length >>> 2) + : ((data.length >>> 2) + 1)); + int[] result; + + if (includeLength) { + result = new int[n + 1]; + result[n] = data.length; + } else { + result = new int[n]; + } + n = data.length; + for (int i = 0; i < n; ++i) { + result[i >>> 2] |= (0x000000ff & data[i]) << ((i & 3) << 3); + } + return result; + } + + private static byte[] toByteArray(int[] data, boolean includeLength) { + int n = data.length << 2; + + if (includeLength) { + int m = data[data.length - 1]; + n -= 4; + if ((m < n - 3) || (m > n)) { + return null; + } + n = m; + } + byte[] result = new byte[n]; + + for (int i = 0; i < n; ++i) { + result[i] = (byte) (data[i >>> 2] >>> ((i & 3) << 3)); + } + return result; + } +} diff --git a/src/main/java/org/m2sec/core/utils/CryptoUtil.java b/src/main/java/org/m2sec/core/utils/CryptoUtil.java index f13fb96..0a27aa6 100644 --- a/src/main/java/org/m2sec/core/utils/CryptoUtil.java +++ b/src/main/java/org/m2sec/core/utils/CryptoUtil.java @@ -12,6 +12,7 @@ import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.math.ec.ECPoint; +import org.m2sec.core.common.XXTEATools; import org.m2sec.core.enums.SymmetricKeyMode; import javax.annotation.Nullable; @@ -54,6 +55,8 @@ public class CryptoUtil { public static final String ALGORITHM_SM4 = "SM4"; public static final String ALGORITHM_SM4_DEFAULT_TRANSFORMATION = "SM4/ECB/PKCS5Padding"; + public static final String ALGORITHM_XXTEA = "XXTEA"; + public static byte[] desEncrypt(String transformation, byte[] data, byte[] secret, Map params) { return symmetricKeyEncrypt(transformation, data, secret, params, ALGORITHM_DES, @@ -184,6 +187,21 @@ private static byte[] sm2Crypt(byte[] data, byte[] key, String modeString, boole } } + public static byte[] teaEncrypt(String transformation, byte[] data, byte[] secret) { + if (transformation != null && !transformation.isBlank() && transformation.equalsIgnoreCase(ALGORITHM_XXTEA)) + return XXTEATools.encrypt(data, secret); + return symmetricKeyEncrypt(transformation, data, secret, null, transformation, + transformation); + } + + + public static byte[] teaDecrypt(String transformation, byte[] data, byte[] secret) { + if (transformation != null && !transformation.isBlank() && transformation.equalsIgnoreCase(ALGORITHM_XXTEA)) + return XXTEATools.decrypt(data, secret); + return symmetricKeyDecrypt(transformation, data, secret, null, transformation, + transformation); + } + public static byte[] sm4Encrypt(@Nullable String transformation, byte[] data, byte[] secret, Map params) { @@ -233,6 +251,7 @@ private static byte[] symmetricKeyDecrypt(@Nullable String transformation, byte[ private static AlgorithmParameterSpec getSymmetricKeyEncryptParameterSpec(String transformation, Map params) { + if (!transformation.contains("/")) return null; String modeStr = transformation.split("/")[1]; SymmetricKeyMode symmetricKeyMode = SymmetricKeyMode.valueOf(modeStr); if (symmetricKeyMode == SymmetricKeyMode.ECB) { diff --git a/src/main/java/org/m2sec/panels/httphook/CodeFileHookerPanel.java b/src/main/java/org/m2sec/panels/httphook/CodeFileHookerPanel.java index 25f0ea2..e40fec5 100644 --- a/src/main/java/org/m2sec/panels/httphook/CodeFileHookerPanel.java +++ b/src/main/java/org/m2sec/panels/httphook/CodeFileHookerPanel.java @@ -317,6 +317,30 @@ private CompletionProvider createCompletionProvider() { "Mac calc -> byte[]", SwingTools.renderSummary("mac calc", "https://github.com/outlaws-bai/Galaxy/blob/main/src/main/java/org/m2sec/core/utils/MacUtil.java", "byte[]", "algorithm(String) HmacMD5 | HmacSHA1 | HmacSHA224 | HmacSHA256|...", "data(byte[]) origin data") )); + // Crypto TEA + provider.addCompletion(new ShorthandCompletion( + provider, + "teaEncrypt", + "CryptoUtil.teaEncrypt(String transformation, byte[] data, byte[] secret)", + "TEA encrypt -> byte[]", + SwingTools.renderSummary("DES encrypt", + "https://github.com/outlaws-bai/Galaxy/blob/main/src/main/java/org/m2sec/core/utils/CryptoUtil.java", + "byte[]", + "transformation(String) TEA | XTEA | XXTEA", + "data(byte[]) origin data", + "secret(byte[]) secret" + ) + )); + provider.addCompletion(new ShorthandCompletion + (provider, + "teaDecrypt", + "CryptoUtil.teaDecrypt(String transformation, byte[] data, byte[] secret)", + "TEA decrypt -> byte[]", + SwingTools.renderSummary("DES decrypt", "https://github.com/outlaws-bai/Galaxy/blob/main/src/main/java" + + "/org/m2sec/core/utils/CryptoUtil.java", "byte[]", "transformation(String) TEA | " + + "XTEA | XXTEA", "data(byte[]) encrypted data", "secret(byte[]) secret" + ) + )); // Crypto - AES provider.addCompletion(new ShorthandCompletion( provider,