Java GUI + exe4j制作加解密桌面程序

2024-04-19 12:28

本文主要是介绍Java GUI + exe4j制作加解密桌面程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

效果图


技术选择

1.创建Maven项目而非普通Java项目;

        方便引入依赖,后期打包时将其它依赖一并打入jar中;

2.安装exe4j将jar文件转换成exe可执行文件;

3.JDK1.8

代码

1.项目结构

客户端访问平台数据格式

{"requestTime": "2023-12-26 15:40:44","data": "","sign": ""
}

平台响应客户端数据格式

{"data":"","requestTime": "2023-12-26 15:40:44","code": "200","message": "","responseTime": "2023-12-26 17:12:20","sign":""
}

2.pom依赖

        因为是单机程序不是Web所以不用导入Web相关依赖

 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.0</version></parent><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.10</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version></dependency></dependencies>

3.加解密工具类

import com.baomidou.dynamic.datasource.toolkit.CryptoUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @Description: 支持AES、DES、RSA加密、数字签名以及生成对称密钥和非对称密钥对*/
public class Crypto {private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;private static final Encoder BASE64_ENCODER = Base64.getEncoder();private static final Decoder BASE64_DECODER = Base64.getDecoder();private static final Map<Algorithm, KeyFactory> KEY_FACTORY_CACHE = new ConcurrentHashMap<>();private static final Map<Algorithm, Cipher> CIPHER_CACHE = new HashMap<>();/*** 生成对称密钥,目前支持的算法有AES、DES* @param algorithm* @return* @throws NoSuchAlgorithmException*/public static String generateSymmetricKey(Algorithm algorithm) throws NoSuchAlgorithmException {KeyGenerator generator = KeyGenerator.getInstance(algorithm.getName());generator.init(algorithm.getKeySize());SecretKey secretKey = generator.generateKey();return BASE64_ENCODER.encodeToString(secretKey.getEncoded());}/*** 生成非对称密钥对,目前支持的算法有RSA、DSA。备注:默认生成的密钥格式为PKCS8* @param algorithm* @return* @throws NoSuchAlgorithmException*/public static AsymmetricKeyPair generateAsymmetricKeyPair(Algorithm algorithm) throws NoSuchAlgorithmException {KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm.getName());generator.initialize(algorithm.getKeySize());KeyPair keyPair = generator.generateKeyPair();String publicKey = BASE64_ENCODER.encodeToString(keyPair.getPublic().getEncoded());String privateKey = BASE64_ENCODER.encodeToString(keyPair.getPrivate().getEncoded());return new AsymmetricKeyPair(publicKey, privateKey);}/*** SHA1签名算法和DSA加密算法结合使用生成数字签名* @param privateKeyText* @param msg* @return 数字签名* @throws Exception*/public static String signBySHA1WithDSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Algorithm.Encryption.DSA, Algorithm.Signing.SHA1WithDSA);}/*** SHA1签名算法和RSA加密算法结合使用生成数字签名* @param privateKeyText 私钥* @param msg 待加签内容* @return 数字签名* @throws Exception*/public static String signBySHA1WithRSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA1WithRSA);}/*** SHA256签名算法和RSA加密算法结合使用生成数字签名* @param privateKeyText 私钥* @param msg 待加签内容* @return 数字签名* @throws Exception*/public static String signBySHA256WithRSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA256WithRSA);}/*** SHA1签名算法和DSA加密算法检验数字签名* @param publicKeyText 公钥* @param msg 待验签内容* @param signatureText 数字* @return 检验是否成功* @throws Exception*/public static boolean verifyBySHA1WithDSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.DSA, Algorithm.Signing.SHA1WithDSA);}/*** SHA1签名算法和RSA加密算法检验数字签名* @param publicKeyText 公钥* @param msg 待验签内容* @param signatureText 签名* @return 校验是否成功* @throws Exception*/public static boolean verifyBySHA1WithRSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA1WithRSA);}/*** SHA256签名算法和RSA加密算法检验数字签名* @param publicKeyText 公钥* @param msg 待验签内容* @param signatureText 签名* @return 校验是否成功* @throws Exception*/public static boolean verifyBySHA256WithRSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Algorithm.Encryption.RSA_ECB_PKCS1, Algorithm.Signing.SHA256WithRSA);}/*** 对称加密* @param secretKey 密钥* @param iv 加密向量,只有CBC模式才支持,如果是CBC则必传* @param plainText 明文* @param algorithm 对称加密算法,如AES、DES* @return* @throws Exception*/public static String encryptSymmetrically(String secretKey, String iv, String plainText, Algorithm algorithm) throws Exception {SecretKey key = decodeSymmetricKey(secretKey, algorithm);IvParameterSpec ivParameterSpec = StringUtils.isBlank(iv) ? null : decodeIv(iv);byte[] plainTextInBytes = plainText.getBytes(DEFAULT_CHARSET);byte[] ciphertextInBytes = transform(algorithm, Cipher.ENCRYPT_MODE, key, ivParameterSpec, plainTextInBytes);return BASE64_ENCODER.encodeToString(ciphertextInBytes);}/*** 对称解密* @param secretKey 密钥* @param iv 加密向量,只有CBC模式才支持,如果是CBC则必传* @param ciphertext 密文* @param algorithm 对称加密算法,如AES、DES* @return* @throws Exception*/public static String decryptSymmetrically(String secretKey, String iv, String ciphertext, Algorithm algorithm) throws Exception {SecretKey key = decodeSymmetricKey(secretKey, algorithm);IvParameterSpec ivParameterSpec = StringUtils.isBlank(iv) ? null : decodeIv(iv);byte[] ciphertextInBytes = BASE64_DECODER.decode(ciphertext);byte[] plainTextInBytes = transform(algorithm, Cipher.DECRYPT_MODE, key, ivParameterSpec, ciphertextInBytes);return new String(plainTextInBytes, DEFAULT_CHARSET);}/*** 非对称加密* @param publicKeyText 公钥* @param plainText 明文* @param algorithm 非对称加密算法* @return* @throws Exception*/public static String encryptAsymmetrically(String publicKeyText, String plainText, Algorithm algorithm) throws Exception {PublicKey publicKey = regeneratePublicKey(publicKeyText, algorithm);byte[] plainTextInBytes = plainText.getBytes(DEFAULT_CHARSET);byte[] ciphertextInBytes = transform(algorithm, Cipher.ENCRYPT_MODE, publicKey, plainTextInBytes);return BASE64_ENCODER.encodeToString(ciphertextInBytes);}/*** 非对称解密* @param privateKeyText 私钥* @param ciphertext 密文* @param algorithm 非对称加密算法* @return* @throws Exception*/public static String decryptAsymmetrically(String privateKeyText, String ciphertext, Algorithm algorithm) throws Exception {PrivateKey privateKey = regeneratePrivateKey(privateKeyText, algorithm);byte[] ciphertextInBytes = BASE64_DECODER.decode(ciphertext);byte[] plainTextInBytes = transform(algorithm, Cipher.DECRYPT_MODE, privateKey, ciphertextInBytes);return new String(plainTextInBytes, DEFAULT_CHARSET);}/*** 生成数字签名* @param privateKeyText 私钥* @param msg 传输的数据* @param encryptionAlgorithm 加密算法,见Algorithm中的加密算法* @param signatureAlgorithm 签名算法,见Algorithm中的签名算法* @return 数字签名* @throws Exception*/public static String doSign(String privateKeyText, String msg, Algorithm encryptionAlgorithm, Algorithm signatureAlgorithm)throws Exception {PrivateKey privateKey = regeneratePrivateKey(privateKeyText, encryptionAlgorithm);// Signature只支持签名算法Signature signature = Signature.getInstance(signatureAlgorithm.getName());signature.initSign(privateKey);signature.update(msg.getBytes(DEFAULT_CHARSET));byte[] signatureInBytes = signature.sign();return BASE64_ENCODER.encodeToString(signatureInBytes);}/*** 数字签名验证* @param publicKeyText 公钥* @param msg 传输的数据* @param signatureText 数字签名* @param encryptionAlgorithm 加密算法,见Algorithm中的加密算法* @param signatureAlgorithm 签名算法,见Algorithm中的签名算法* @return 校验是否成功* @throws Exception*/public static boolean doVerify(String publicKeyText, String msg, String signatureText, Algorithm encryptionAlgorithm,Algorithm signatureAlgorithm) throws Exception {PublicKey publicKey = regeneratePublicKey(publicKeyText, encryptionAlgorithm);Signature signature = Signature.getInstance(signatureAlgorithm.getName());signature.initVerify(publicKey);signature.update(msg.getBytes(DEFAULT_CHARSET));return signature.verify(BASE64_DECODER.decode(signatureText));}/*** 将密钥进行Base64位解码,重新生成SecretKey实例* @param secretKey 密钥* @param algorithm 算法* @return*/private static SecretKey decodeSymmetricKey(String secretKey, Algorithm algorithm) {byte[] key = BASE64_DECODER.decode(secretKey);return new SecretKeySpec(key, algorithm.getName());}private static IvParameterSpec decodeIv(String iv) {byte[] ivInBytes = BASE64_DECODER.decode(iv);return new IvParameterSpec(ivInBytes);}private static PublicKey regeneratePublicKey(String publicKeyText, Algorithm algorithm)throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] keyInBytes = BASE64_DECODER.decode(publicKeyText);KeyFactory keyFactory = getKeyFactory(algorithm);// 公钥必须使用RSAPublicKeySpec或者X509EncodedKeySpecKeySpec publicKeySpec = new X509EncodedKeySpec(keyInBytes);PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);return publicKey;}private static PrivateKey regeneratePrivateKey(String key, Algorithm algorithm) throws Exception {byte[] keyInBytes = BASE64_DECODER.decode(key);KeyFactory keyFactory = getKeyFactory(algorithm);// 私钥必须使用RSAPrivateCrtKeySpec或者PKCS8EncodedKeySpecKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyInBytes);PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);return privateKey;}private static KeyFactory getKeyFactory(Algorithm algorithm) throws NoSuchAlgorithmException {KeyFactory keyFactory = KEY_FACTORY_CACHE.get(algorithm);if (keyFactory == null) {keyFactory = KeyFactory.getInstance(algorithm.getName());KEY_FACTORY_CACHE.put(algorithm, keyFactory);}return keyFactory;}private static byte[] transform(Algorithm algorithm, int mode, Key key, byte[] msg) throws Exception {return transform(algorithm, mode, key, null, msg);}private static byte[] transform(Algorithm algorithm, int mode, Key key, IvParameterSpec iv, byte[] msg) throws Exception {Cipher cipher = CIPHER_CACHE.get(algorithm);// double check,减少上下文切换if (cipher == null) {synchronized (CryptoUtils.class) {if ((cipher = CIPHER_CACHE.get(algorithm)) == null) {cipher = determineWhichCipherToUse(algorithm);CIPHER_CACHE.put(algorithm, cipher);}cipher.init(mode, key, iv);return cipher.doFinal(msg);}}synchronized (CryptoUtils.class) {cipher.init(mode, key, iv);return cipher.doFinal(msg);}}private static Cipher determineWhichCipherToUse(Algorithm algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {Cipher cipher;String transformation = algorithm.getTransformation();// 官方推荐的transformation使用algorithm/mode/padding组合,SunJCE使用ECB作为默认模式,使用PKCS5Padding作为默认填充if (StringUtils.isNotEmpty(transformation)) {cipher = Cipher.getInstance(transformation);} else {cipher = Cipher.getInstance(algorithm.getName());}return cipher;}/*** 算法分为加密算法和签名算法,更多算法实现见:<br/>* <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">jdk8中的标准算法</a>*/public static class Algorithm {public interface Encryption {Algorithm AES_ECB_PKCS5 = new Algorithm("AES", "AES/ECB/PKCS5Padding", 128);Algorithm AES_CBC_PKCS5 = new Algorithm("AES", "AES/CBC/PKCS5Padding", 128);Algorithm DES_ECB_PKCS5 = new Algorithm("DES", "DES/ECB/PKCS5Padding", 56);Algorithm DES_CBC_PKCS5 = new Algorithm("DES", "DES/CBC/PKCS5Padding", 56);Algorithm RSA_ECB_PKCS1 = new Algorithm("RSA", "RSA/ECB/PKCS1Padding", 1024);Algorithm DSA = new Algorithm("DSA", 1024);}public interface Signing {Algorithm SHA1WithDSA = new Algorithm("SHA1withDSA", 1024);Algorithm SHA1WithRSA = new Algorithm("SHA1WithRSA", 2048);Algorithm SHA256WithRSA = new Algorithm("SHA256WithRSA", 2048);}@Getterprivate String name;@Getterprivate String transformation;@Getterprivate int keySize;public Algorithm(String name, int keySize) {this(name, null, keySize);}public Algorithm(String name, String transformation, int keySize) {this.name = name;this.transformation = transformation;this.keySize = keySize;}}@Data@NoArgsConstructor@AllArgsConstructorpublic static class AsymmetricKeyPair {private String publicKey;private String privateKey;}
}
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;/*** @Description: Rsa加解密*/
public class Rsa {private static final String ALGORITHM = "RSA";//private static final String ALGORITHM = "RSA/ECB/PKCS1Padding";private static final String UTF8 = StandardCharsets.UTF_8.name();/*** rsa单次最大加密的文明大小*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** rsa单次最大解密的密文大小*/private static final int MAX_DECRYPT_BLOCK = 128;/*** 生成经过base64编码后的密钥对(公钥和私钥)并存储在文件中*/public Map<String,String> getPriAndPubKey() throws Exception{KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(1024);//通过keyPair生成器生成keyPairKeyPair keyPair = keyPairGenerator.generateKeyPair();/*公钥*/PublicKey publicKey = keyPair.getPublic();//把对象转成字节数组byte[] encoded = publicKey.getEncoded();String publicKeyBase64Stri = Base64.encodeBase64String(encoded);//String publicKeyBase64Stri = new ByteFromStr().convertBytes2HexStr(encoded);/*私钥*/PrivateKey privateKey = keyPair.getPrivate();//把对象转成字节数组byte[] privateKeyEncoded = privateKey.getEncoded();String privateKeyBase64Stri = Base64.encodeBase64String(privateKeyEncoded);HashMap<String, String> hashMap = new HashMap<>();hashMap.put("public",publicKeyBase64Stri);hashMap.put("private",privateKeyBase64Stri);return hashMap;}/*** 从生成好的公钥文件rsa.pub(这里的公钥文件是通过Base64编码之后存储的数据)获取公钥对象* @return*/public PublicKey getPulickey(String publicKeyStr)throws Exception{//base64解码,获取字节数组byte[] decodeBase64 = Base64.decodeBase64(publicKeyStr);//传入算法名字”RAS“KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);//传入key的规则,对于公钥的规则就是x509,将公钥的字符串传入公钥规则里面X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decodeBase64);return keyFactory.generatePublic(x509EncodedKeySpec);}/*** 从生成好的私钥文件rsa.pri(这里的公钥文件是通过Base64编码之后存储的数据)获取私钥对象* @return*/public PrivateKey getPrivateKey(String privateKeyStr)throws Exception{//base64解码,获取字节数组byte[] decodeBase64 = Base64.decodeBase64(privateKeyStr);//传入算法名字”RAS“KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);//传入key的规则,对于私钥的规则就是PKCS8,将公钥的字符串传入公钥规则里面PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decodeBase64);return keyFactory.generatePrivate(pkcs8EncodedKeySpec);}/*** 加密* @param originalCont 原始内容* @param key 公钥或者私钥* @return base64编码后的加密内容* @throws Exception*/public String encrypt(String originalCont, Key key) throws Exception{Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE,key);byte[] bytes = doCodec(cipher,originalCont.getBytes(UTF8),MAX_ENCRYPT_BLOCK);return Base64.encodeBase64String(bytes);}/*** 解密* @param encryptedStr 加密后内容* @param key 公钥或者私钥* @return 原始内容* @throws Exception*/public String decrypt(String encryptedStr, Key key) throws Exception{try {byte[] decodeBase64 = Base64.decodeBase64(encryptedStr);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE,key);byte[] decryptedBytes = doCodec(cipher,decodeBase64,MAX_DECRYPT_BLOCK);return new String(decryptedBytes);}catch (Exception e){e.printStackTrace();
//            throw new AuthenticationServiceException("参数解密异常:"+e.getMessage());throw new RuntimeException("参数解密异常");}}/*** 执行加密或者解密* @param cipher* @param decodeBase64* @param maxDecryptBlock* @return*/private byte[] doCodec(Cipher cipher, byte[] decodeBase64, int maxDecryptBlock) throws Exception{//获取字节长度int inputLen = decodeBase64.length;//迁移量int offset = 0;//本次完成加密之后的数组byte[] cache;//循环的次数int i= 0;//ByteArrayOutputStream baos = new ByteArrayOutputStream();while ((inputLen-offset)>0){if ((inputLen - offset)>maxDecryptBlock){//第三个参数,要处理的长度cache = cipher.doFinal(decodeBase64,offset,maxDecryptBlock);}else {cache = cipher.doFinal(decodeBase64,offset,inputLen-offset);}baos.write(cache,0,cache.length);i++;offset = i*maxDecryptBlock;}//加密或者解密的结果byte[] bytes = baos.toByteArray();baos.close();return bytes;}
}

4.GUI图形界面及相关控制逻辑

import cn.encrypt.util.Crypto;
import cn.encrypt.util.Rsa;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.PrivateKey;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/*** 加解密工具(GUI)**      完整验签流程应为:*            1.平台生成AES秘钥,此秘钥告知客户端双方都使用此秘钥加密data节点中的JSON字符串数据;*            2.平台与客户端各自生成一对RSA公私钥;互相交换公钥。该公钥用于对方解密sign中的签名信息【sign产生规则(RSA私钥加密):RSA(MD5(业务报文JSON字符串))】;*                  2.1.AES解密data节点中的原文JSON字符串数据;*                  2.2.将2.1拿到的原文字符串信息进行md5得到签名信息1;*                  2.3.通过对方RSA公钥解密sign中数据得到签名信息2;*                  2.4.判断两个签名信息是否相等,若相等代表数据未被篡改;*/
public class Main {/*** 主函数* */public static void main(String[] args) {int gap = 10;// AES默认值String AES_MRZ = "KCxblY+b4iqhU4ELDl4xXQ==";// 用户私钥默认值(用于加密签名sign,签名加密规则:RSA(md5(字符串JSON入参))),该sign用于服务器检查客户端上传参数中途是否被篡改。String YHSY_MRZ = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALNv7UQzEucTr/1MSif1kGeSsfTfY01XOkmr7ZO5vP95n/KvTV89o0K1xfk1hGMAp+xxflyHQThGz2LzUTQlXQXQ3fHUVDD5rYirtF03dX5s1MOrhkaCru5/IVUT83k0V3706Yo00PjrQTWx54XLyPVWwok0po7/e1VWTGT5DJHJAgMBAAECgYAI6Xs4Uu0SawjnpL1eJLUqX7/U8K9m7PkpJY/kMWpwqeLG0+wc2dvc+Vg+22ia3jJ47N4gzFrx55pvSLR0yZJIHQ/PqaJ0qR1BgTBaZBAR/S2nmoLo2LxTOh1sG1V0H2J7bPv3FAP4+4CQ5MtbeJFW2IDAQcfTv01TugftEhw8XQJBAP54vzNQPNKOmT5bVxVxIfetm/DHtLduJ5yDX3Lh43XM3rXmhPf886nuQ4g9Yzm1g9Of8qB7dgC4xrXg8NOmzKMCQQC0g9BImwOF5gYfGpw9WbC/vU/TttV1l3M/XvHfjMpzisxUxEEXJtZX7nsjvwjbyMYSTn4n8Rel4bMXXPlztQKjAkBw4AJ/smGoTBRxcnaoTixw/pMjNJJWowfzBtr5zHTmtd879GqazZsPj15pOkGfQYKeBl7LDLiFDXEnEAYC/APdAkARO0P2qlV7wqly7qdbc+RbaUblft6BiyOFORr9rALnZKh8rv9Hpn1vh2RZ1TKTSGcf+D4yseEABLuDz2xAj1bhAkAsnoLWt9O+PZtPOSmmxLD+/6aS786mjG0SuSPUwt07VX43Rv2xUHuKvcJ9KGd2l5iitmG+KFvV8ayLYrA1hWil";JFrame f = new JFrame("企业加解密工具(内部版)V1.0");f.setSize(410, 400);f.setLocation(200, 200);f.setLayout(null);JPanel pInput = new JPanel();pInput.setBounds(gap, gap, 375, 120);pInput.setLayout(new GridLayout(4,3,gap,gap));JLabel aesKey = new JLabel("AES:");JTextField aesKeyText = new JTextField(AES_MRZ); // 在构造函数中传入“字符串参数”为其设置默认值JLabel yhsy = new JLabel("用户私钥:");JTextField yhsyText = new JTextField(YHSY_MRZ); // 在构造函数中传入“字符串参数”为其设置默认值JLabel param = new JLabel("入参明文:");JTextField paramText = new JTextField();JLabel rsp = new JLabel("响应密文:");JTextField rspText = new JTextField();JButton b = new JButton("加密");JButton c = new JButton("解密");// AESpInput.add(aesKey);pInput.add(aesKeyText);// 用户私钥pInput.add(yhsy);pInput.add(yhsyText);// 请求入参pInput.add(param);pInput.add(paramText);// 响应入参pInput.add(rsp);pInput.add(rspText);// 文本域JTextArea ta = new JTextArea();c.setBounds(200, 120 + 30, 80, 30); // 设置解密按钮坐标b.setBounds(70, 120 + 30, 80, 30); // 设置加密按钮坐标ta.setBounds(gap, 150 + 60, 375, 120); // 设置文本域坐标// 创建一个滚动面板,并将文本域添加到滚动面板中JScrollPane scrollPane = new JScrollPane(ta);scrollPane.setBounds(gap, 150 + 60, 375, 120);f.add(pInput); // 抬头及输入框添加到Framef.add(b); // 按钮添加到Framef.add(c); // 按钮添加到Framef.add(scrollPane);// 滚动面板添加到Framef.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setVisible(true);// 加密按钮监听b.addActionListener(new ActionListener(){boolean checkedpass = true;public void actionPerformed(ActionEvent e){checkedpass = true;// 非空校验checkEmpty(aesKeyText,"AES");checkEmpty(yhsyText,"用户私钥");checkEmpty(paramText,"入参明文");String aes = aesKeyText.getText();String yhsy = yhsyText.getText();String params = paramText.getText();if(checkedpass){// data 加密String data = "";String sign = "";// JSON格式校验if(!JSONUtil.isJson(params)){ta.setText("");ta.append("JSON格式错误!");return;}try {data = Crypto.encryptSymmetrically(aes, null, params, Crypto.Algorithm.Encryption.AES_ECB_PKCS5);} catch (Exception e1) {ta.setText("");ta.append("加密失败!");return;}// sign 加密String md5Txet = SecureUtil.md5(params);// 用户私钥加密Rsa rsa = new Rsa();PrivateKey yhsyKey = null;try {yhsyKey = rsa.getPrivateKey(yhsy);sign = rsa.encrypt(md5Txet, yhsyKey);} catch (Exception e1) {ta.setText("");ta.append("加密失败!");return;}Map<String, String> result = new HashMap<>();result.put("data",data);result.put("sign",sign);result.put("requestTime", LocalDateTimeUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));ta.setText("");ta.append(JSONUtil.toJsonStr(result));}}// 检验是否为空private void checkEmpty(JTextField tf, String msg){if(!checkedpass)return;String value = tf.getText();if(value.length()==0){JOptionPane.showMessageDialog(f, msg + " 不能为空");tf.grabFocus();checkedpass = false;}}});// 解密按钮监听c.addActionListener(new ActionListener(){boolean checkedpass = true;public void actionPerformed(ActionEvent e){checkedpass = true;// 非空校验checkEmpty(aesKeyText,"AES");checkEmpty(rspText,"响应密文");String aes = aesKeyText.getText();String params = rspText.getText();if(checkedpass){// JSON格式校验if(!JSONUtil.isJson(params)){ta.setText("");ta.append("JSON格式错误!");return;}// 响应数据String rsp = null;JSONObject obj = JSONUtil.toBean(params, JSONObject.class);if("200".equals(obj.getStr("code"))){String data = obj.getStr("data");if(StrUtil.isBlank(data)){ta.setText("");ta.append("数据格式不完整"); // 响应数据缺少data节点return;}/*** 说明:*      此处只对data节点进行AES解密。不模拟使用“平台公钥”对服务器响应的sign进行验签。因为不模拟服务器端的签名,所以代码中未声明“平台公钥”*/try {rsp = Crypto.decryptSymmetrically(aes, null, data, Crypto.Algorithm.Encryption.AES_ECB_PKCS5);ta.setText("");ta.append(rsp); // 解密成功直接返回return;} catch (Exception e1) {ta.setText("");ta.append("解密失败!");return;}}ta.setText("");ta.append(params); // 非200状态码来解密时直接返回原送参数据}}//检验是否为空private void checkEmpty(JTextField tf, String msg){if(!checkedpass)return;String value = tf.getText();if(value.length()==0){JOptionPane.showMessageDialog(f, msg + " 不能为空");tf.grabFocus();checkedpass = false;}}});}
}

项目打包

        包含将Maven中依赖用到的jar一并打入到当前程序的jar中;不会的可以看下面的文章;

传送门文章浏览阅读318次。前段时间需要给接口对接方提供一个Jar包,其内容包含接口调用方参数加签,服务提供方响应验签,以及为调用方组装服务提供方需要的入参格式。打工具类Jar实现的目标:1.工具类项目使用Maven管理方便在项目中引入其它需要的依赖;2.工具类项目打好Jar后,此Jar可直接在其它地方导入使用(类似于JDBC驱动Jar);3.打好的工具类Jar中,包含工具类项目使用到的Maven依赖对应的源码包;4.使用IDEA自带的打包方式,不使用Maven打包插件进行打包;_idea打引用jar包 选择携带依赖https://blog.csdn.net/weixin_45876411/article/details/132853766

制作exe执行程序

        这篇文章很nice,傻瓜式教程这里就不再重复赘述;传送门文章浏览阅读8.9k次,点赞35次,收藏186次。目录1.GUI插件1.1 下载GUI绘制插件1.GUI插件使用IDEA的朋友们,可能比较头疼了,为什么这里要去下载eclipse的插件,IDEA里面没有吗?其实是有的,但是都是要付费使用的,不得已,我们只有使用eclipse来帮助我们绘制GUI的操作了,GUI界面生成之后,后面的逻辑代码编写,我们还是会在IDEA里面操作。1.1 下载GUI绘制插件下载地址:windowbuilder下载点击link点击下载,从外网下载,速度可能比较慢,建议使用迅雷下载。1.2 ._java开发windows桌面程序https://blog.csdn.net/Jeffhan_java/article/details/123403997

测试

客户端参数加密测试

模拟客户端将明文参数加密成平台接口需要的参数格式;

入参:

{"id":1001}

响应:

{"requestTime":"2024-04-18 16:48:43","data":"bHVEPUh9PFVIJ6lmuhDhrA==","sign":"gPOMELGlFZuj/P7QvdvZf61cSMg4iQ1dUR9/J1BzsZtsIO5dbb2fmwA3UsyeIu7DkDwFxfpfzSKMRgdLFRKDX9IFyoWhBGbmnGWpJn6wysjVErBNiD7rYi5ioK3oSDSJFuPMnmJTKPoodumz3KO4Jy8is2t4icFMN+7LXTI3YCI="}

平台响应解密测试

模拟客户端收到平台处理完后的数据进行解密;

入参

{"data":"U32bMclk9/SQeE46F4sIv9Ns4BqyQZvR71bOADYZpPdOcd3+rJdEkqzA+jgoVUzS67H1tWslzAX6DOXNDTAG1bbDC45eNXqsqESy1rSZoM4=","requestTime":"2024-04-18 17:12:16","code":"200","message":"","responseTime":"2024-04-18 17:12:20","sign":"此处不模拟平台使用平台私钥加密sign签名"}

响应

{"id":1001,"name":"小明","address":"四川省成都市","age":18}

另附项目源码及exe4j安装程序包 ,需要可自行下载;

这篇关于Java GUI + exe4j制作加解密桌面程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/917535

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2