diff --git a/src/main/java/de/usd/cstchef/Utils.java b/src/main/java/de/usd/cstchef/Utils.java index ee3a04a..a324daf 100644 --- a/src/main/java/de/usd/cstchef/Utils.java +++ b/src/main/java/de/usd/cstchef/Utils.java @@ -75,6 +75,8 @@ import de.usd.cstchef.operations.encryption.DesEncryption; import de.usd.cstchef.operations.encryption.RsaDecryption; import de.usd.cstchef.operations.encryption.RsaEncryption; +import de.usd.cstchef.operations.encryption.SM4Decryption; +import de.usd.cstchef.operations.encryption.SM4Encryption; import de.usd.cstchef.operations.extractors.HttpBodyExtractor; import de.usd.cstchef.operations.extractors.HttpCookieExtractor; import de.usd.cstchef.operations.extractors.HttpGetExtractor; @@ -99,6 +101,7 @@ import de.usd.cstchef.operations.hashing.SHA1; import de.usd.cstchef.operations.hashing.SHA2; import de.usd.cstchef.operations.hashing.SHA3; +import de.usd.cstchef.operations.hashing.SM3; import de.usd.cstchef.operations.hashing.Skein; import de.usd.cstchef.operations.hashing.Tiger; import de.usd.cstchef.operations.hashing.Whirlpool; @@ -120,6 +123,7 @@ import de.usd.cstchef.operations.signature.JWTDecode; import de.usd.cstchef.operations.signature.JWTSign; import de.usd.cstchef.operations.signature.RsaSignature; +import de.usd.cstchef.operations.signature.SM2Signature; import de.usd.cstchef.operations.signature.SoapMultiSignature; import de.usd.cstchef.operations.signature.XmlFullSignature; import de.usd.cstchef.operations.signature.XmlMultiSignature; @@ -300,7 +304,7 @@ public static Class[] getOperationsDev() { Multiply.class, MultiplyList.class, NoOperation.class, NumberCompare.class, Prefix.class, RandomNumber.class, RandomUUID.class, ReadFile.class, RegexExtractor.class, Reverse.class, Replace.class, - RIPEMD.class, RsaDecryption.class, RsaEncryption.class, RsaSignature.class, RegexMatch.class, + RIPEMD.class, RsaDecryption.class, RsaEncryption.class, RsaSignature.class, SM2Signature.class, SM3.class, SM4Encryption.class, SM4Decryption.class, RegexMatch.class, SetIfEmpty.class, SHA1.class, SHA2.class, SHA3.class, Skein.class, SplitAndSelect.class, StaticString.class, StoreVariable.class, Sub.class, Substring.class, Uppercase.class, Lowercase.class, Subtraction.class, diff --git a/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java b/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java index 5a38482..7758654 100644 --- a/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java +++ b/src/main/java/de/usd/cstchef/operations/encryption/CipherUtils.java @@ -41,6 +41,11 @@ private void getCipherInfos() { } } } + // Add info for SM4 + CipherInfo info = new CipherInfo(); + info.setModes(new String[]{"ECB", "CBC", "CTR", "OFB", "CFB"}); + info.setPaddings(new String[]{"NOPADDING", "PKCS5PADDING"}); + algos.put("SM4", info); } public static CipherUtils getInstance() { diff --git a/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java b/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java index 11a8736..01a602c 100644 --- a/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java +++ b/src/main/java/de/usd/cstchef/operations/encryption/CryptOperation.java @@ -1,5 +1,7 @@ package de.usd.cstchef.operations.encryption; +import java.security.Security; + import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -9,6 +11,7 @@ import burp.api.montoya.core.ByteArray; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import de.usd.cstchef.operations.Operation; @@ -17,6 +20,10 @@ public abstract class CryptOperation extends Operation { + static { + Security.addProvider(new BouncyCastleProvider()); + } + private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" }; protected String algorithm; @@ -41,7 +48,13 @@ protected byte[] crypt(byte[] input, int cipherMode, String algorithm, String mo SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm); IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes()); - Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, mode, padding)); + Cipher cipher; + if(algorithm.equals("SM4")){ + cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, mode, padding), BouncyCastleProvider.PROVIDER_NAME); + } + else{ + cipher = Cipher.getInstance(String.format("%s/%s/%s", algorithm, mode, padding)); + } if( mode.equals("ECB") ) { cipher.init(cipherMode, secretKeySpec); diff --git a/src/main/java/de/usd/cstchef/operations/encryption/SM4Decryption.java b/src/main/java/de/usd/cstchef/operations/encryption/SM4Decryption.java new file mode 100644 index 0000000..5cbd938 --- /dev/null +++ b/src/main/java/de/usd/cstchef/operations/encryption/SM4Decryption.java @@ -0,0 +1,13 @@ +package de.usd.cstchef.operations.encryption; + +import de.usd.cstchef.operations.OperationCategory; +import de.usd.cstchef.operations.Operation.OperationInfos; + +@OperationInfos(name = "SM4 Decryption", category = OperationCategory.ENCRYPTION, description = "Decrypts via the SM4 algorithm.") +public class SM4Decryption extends DecryptionOperation { + + public SM4Decryption() { + super("SM4"); + } + +} diff --git a/src/main/java/de/usd/cstchef/operations/encryption/SM4Encryption.java b/src/main/java/de/usd/cstchef/operations/encryption/SM4Encryption.java new file mode 100644 index 0000000..9af4d74 --- /dev/null +++ b/src/main/java/de/usd/cstchef/operations/encryption/SM4Encryption.java @@ -0,0 +1,13 @@ +package de.usd.cstchef.operations.encryption; + +import de.usd.cstchef.operations.OperationCategory; +import de.usd.cstchef.operations.Operation.OperationInfos; + +@OperationInfos(name = "SM4 Encryption", category = OperationCategory.ENCRYPTION, description = "Encrypts via the SM4 algorithm.") +public class SM4Encryption extends EncryptionOperation { + + public SM4Encryption() { + super("SM4"); + } + +} diff --git a/src/main/java/de/usd/cstchef/operations/hashing/SM3.java b/src/main/java/de/usd/cstchef/operations/hashing/SM3.java new file mode 100644 index 0000000..1296445 --- /dev/null +++ b/src/main/java/de/usd/cstchef/operations/hashing/SM3.java @@ -0,0 +1,13 @@ +package de.usd.cstchef.operations.hashing; + +import de.usd.cstchef.operations.OperationCategory; +import de.usd.cstchef.operations.Operation.OperationInfos; + +@OperationInfos(name = "SM3", category = OperationCategory.HASHING, description = "The SM3 algorithm") +public class SM3 extends HashOperation { + + public SM3() { + super("SM3"); + } + +} diff --git a/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java b/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java index 94fe57a..cdb8436 100644 --- a/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java +++ b/src/main/java/de/usd/cstchef/operations/signature/RsaSignature.java @@ -59,7 +59,7 @@ public void createMyUI() { super.createMyUI(); SignatureUtils utils = SignatureUtils.getInstance(); - this.algos = new JComboBox<>(utils.getRsaAlgos()); + this.algos = new JComboBox<>(utils.getAlgos("RSA")); this.addUIElement("Padding", this.algos); this.inputMode = new JComboBox<>(inOutModes); diff --git a/src/main/java/de/usd/cstchef/operations/signature/SM2Signature.java b/src/main/java/de/usd/cstchef/operations/signature/SM2Signature.java new file mode 100644 index 0000000..15d1fe5 --- /dev/null +++ b/src/main/java/de/usd/cstchef/operations/signature/SM2Signature.java @@ -0,0 +1,70 @@ +package de.usd.cstchef.operations.signature; + +import java.security.Signature; + +import javax.swing.JComboBox; + +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; + +import burp.api.montoya.core.ByteArray; +import de.usd.cstchef.Utils.MessageType; +import de.usd.cstchef.operations.Operation.OperationInfos; +import de.usd.cstchef.operations.OperationCategory; + +@OperationInfos(name = "SM2 Signature", category = OperationCategory.SIGNATURE, description = "Create a SM2 signature") +public class SM2Signature extends KeystoreOperation { + + private static String[] inOutModes = new String[] { "Raw", "Hex", "Base64" }; + + protected JComboBox algos; + protected JComboBox inputMode; + protected JComboBox outputMode; + + public SM2Signature() { + super(); + this.createMyUI(); + } + + protected ByteArray perform(ByteArray input, MessageType messageType) throws Exception { + if( !this.keyAvailable.isSelected() ) + throw new IllegalArgumentException("No private key available."); + + String algo = (String)algos.getSelectedItem(); + Signature signature = Signature.getInstance(algo); + + String selectedInputMode = (String)inputMode.getSelectedItem(); + String selectedOutputMode = (String)outputMode.getSelectedItem(); + + if( selectedInputMode.equals("Hex") ) + input = factory.createByteArray(Hex.decode(input.getBytes())); + if( selectedInputMode.equals("Base64") ) + input = factory.createByteArray(Base64.decode(input.getBytes())); + + signature.initSign(this.selectedEntry.getPrivateKey()); + signature.update(input.getBytes()); + ByteArray result = factory.createByteArray(signature.sign()); + + if( selectedOutputMode.equals("Hex") ) + result = factory.createByteArray(Hex.encode(result.getBytes())); + if( selectedOutputMode.equals("Base64") ) + result = factory.createByteArray(Base64.encode(result.getBytes())); + + return result; + } + + public void createMyUI() { + + super.createMyUI(); + SignatureUtils utils = SignatureUtils.getInstance(); + + this.algos = new JComboBox<>(utils.getAlgos("SM2")); + this.addUIElement("Padding", this.algos); + + this.inputMode = new JComboBox<>(inOutModes); + this.addUIElement("Input", this.inputMode); + + this.outputMode = new JComboBox<>(inOutModes); + this.addUIElement("Output", this.outputMode); + } +} diff --git a/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java b/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java index f474b2b..3c0a271 100644 --- a/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java +++ b/src/main/java/de/usd/cstchef/operations/signature/SignatureUtils.java @@ -35,8 +35,9 @@ public static SignatureUtils getInstance() { public String[] getAlgos() { return algos.toArray(new String[0]); } - public String[] getRsaAlgos() { - List rsaAlgos = algos.stream().filter(p -> p.contains("RSA")).collect(Collectors.toList()); + public String[] getAlgos(String s) { + List rsaAlgos = algos.stream().filter(p -> p.contains(s)).collect(Collectors.toList()); return rsaAlgos.toArray(new String[0]); } + }