224 lines
7.9 KiB
Java
224 lines
7.9 KiB
Java
package com.example.sjkbf.util;
|
||
|
||
import cn.hutool.core.codec.Base64;
|
||
import cn.hutool.crypto.asymmetric.KeyType;
|
||
import cn.hutool.crypto.asymmetric.RSA;
|
||
|
||
import java.io.ByteArrayInputStream;
|
||
import java.io.ByteArrayOutputStream;
|
||
import java.io.IOException;
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.util.Arrays;
|
||
import java.util.zip.GZIPInputStream;
|
||
import java.util.zip.GZIPOutputStream;
|
||
|
||
public class RSATooL {
|
||
|
||
|
||
private static String prkey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANp/KnuAZq609lnc\n" +
|
||
"jciVgt/xDLDEaKC+DSuSZc9o/fgLqweL/8Yu5iPAzoBQlO1t+jSkI2YuoFsKKK7O\n" +
|
||
"QFcSoz4Z5Lb7vOG7XJ4Re/6L2LJIU9tjJ3LznW5WKnuiqxs0ziIZilLkRE0P1di6\n" +
|
||
"FIZQUjmn2KQ2y/P7PuviJPat3y+vAgMBAAECgYEAmn64h0MvV/FVEA1Ho8E0HSzQ\n" +
|
||
"kF0Qrjg0D88gdhwDGFUHxfpUDMo0qKs4WLqh05CkDnzRGvt1H2p7gb8M94SSL5SX\n" +
|
||
"mCR2ZLiCQJy5tZpQNRUt9P67upLcDcKJ6YPujcuEdlo0pzKGGMZk8Uvh05S9lnwl\n" +
|
||
"yWJeEk4G7q5Aalz8vIECQQDwBVJH60Gd2St/GS4dCtXwHTO9HJZRaWEkaXPgVbXI\n" +
|
||
"vqv+jtD4HpzDCpgv/kUK0fnb4V/9/LM1SHOedVMfmh0fAkEA6QsChdHiU1lHfL1b\n" +
|
||
"Z3Uvxvi/Zk8i0ryzBaYudrzNmb7iJcssJPPty3KTjihgvw2W36GV+2GlQBEjOf2B\n" +
|
||
"2WgLcQJBAO66XDxsIbd+aWThBpycSm2one1aoagXyCcPO9HFbilcfHWUVwRybjkQ\n" +
|
||
"MI6LuOAqOPoaD//vd89nYJga2bJ09sECQFmXRPoDTVozqXr4JSqp75szyAliBQY1\n" +
|
||
"SzGxyI0XWodvzesvp6HxMQsU2ks9lKv+YnFI4qsIyAnQTNWfcwsMp9ECQDba0LJV\n" +
|
||
"xI0SIznsVtBb7T5Ir9ppLKx1QTNcytkjHxmQqWGy+57ojjQ6GV3z4fSwNGjIhsOT\n" +
|
||
"DFgz0gEcRr13bRk=";
|
||
private static String pubkey =
|
||
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDafyp7gGautPZZ3I3IlYLf8Qyw\n" +
|
||
"xGigvg0rkmXPaP34C6sHi//GLuYjwM6AUJTtbfo0pCNmLqBbCiiuzkBXEqM+GeS2\n" +
|
||
"+7zhu1yeEXv+i9iySFPbYydy851uVip7oqsbNM4iGYpS5ERND9XYuhSGUFI5p9ik\n" +
|
||
"Nsvz+z7r4iT2rd8vrwIDAQAB";
|
||
static RSA rsa2 = new RSA(prkey, pubkey);
|
||
|
||
/**
|
||
* 解密
|
||
* @param str
|
||
* @return
|
||
*/
|
||
public static String decrypt(String str){
|
||
|
||
str= str.replaceAll(" ","+");
|
||
byte[] decrypt2 = rsa2.decrypt(str, KeyType.PrivateKey);
|
||
String s = new String(decrypt2);
|
||
String[] split = s.split("");
|
||
s = split[0];
|
||
return s;
|
||
}
|
||
|
||
/**
|
||
* 加密
|
||
* @param str
|
||
* @return
|
||
*/
|
||
public static String encryption(String str){
|
||
return Base64.encode(rsa2.encrypt(str, KeyType.PrivateKey));
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 使用RSA公钥解密
|
||
* @param encryptedData 加密后的数据(Base64编码)
|
||
* @return 解密后的原始字符串
|
||
*/
|
||
public static String decryptByPublicKey( String encryptedData) {
|
||
|
||
|
||
// 解密步骤:
|
||
// 1. 将Base64编码的加密数据解码为字节数组
|
||
// 2. 使用公钥解密(指定KeyType.PublicKey)
|
||
// 3. 将解密后的字节数组转换为字符串
|
||
byte[] decryptedBytes = rsa2.decrypt(Base64.decode(encryptedData), KeyType.PublicKey);
|
||
|
||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||
}
|
||
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println(decompress("H4sIAAAAAAAAAKtWyk6tVLJSUggKdgzJz/fRS81LLqosKMnMz9MAyhTrleQHlxRl5qVraCrVAgAXNYHCLQAAAA=="));
|
||
}
|
||
|
||
//异或加密
|
||
public static byte[] Makecode(byte[] pstr,int[] Key) {
|
||
byte[] Str = pstr;
|
||
|
||
for (int i = 0; i < Str.length; i++) {
|
||
byte sbuf = Str[i];
|
||
Str[i] = MakecodeChar(sbuf, Key[i % 20], Key[(i + 18) % 20]);
|
||
}
|
||
|
||
return Str;
|
||
}
|
||
|
||
//字符串异或
|
||
public static String encryptDecrypt(String input, String key) {
|
||
StringBuilder output = new StringBuilder(input);
|
||
int keyLength = key.length();
|
||
|
||
for (int i = 0; i < input.length(); i++) {
|
||
// 对每个字符进行异或运算
|
||
output.setCharAt(i, (char) (input.charAt(i) ^ key.charAt(i % keyLength)));
|
||
}
|
||
|
||
return output.toString();
|
||
}
|
||
|
||
|
||
//单个字符加密
|
||
public static byte MakecodeChar(byte c, int key, int key2) {
|
||
return (byte) ((((c + key) ^ key2) ^ key) + 1);
|
||
}
|
||
|
||
|
||
/**
|
||
* 单个字符解密,对应C++的CutcodeChar
|
||
* @param c 待解密的字符(Java中用byte表示,对应C++的char)
|
||
* @param key 第一个密钥
|
||
* @param key2 第二个密钥
|
||
* @return 解密后的字符(byte)
|
||
*/
|
||
public static byte cutcodeChar(byte c, int key, int key2) {
|
||
// 对应C++的:(((c - 1) ^ key) ^ key2) - key
|
||
// 注意:Java中byte是8位有符号数,运算时会自动提升为int,最后强转为byte
|
||
int step1 = (c - 1) ^ key;
|
||
int step2 = step1 ^ key2;
|
||
int result = step2 - key;
|
||
return (byte) result;
|
||
}
|
||
|
||
/**
|
||
* 字节数组解密,对应C++的Cutecode
|
||
* @param pstr 待解密的字节数组(对应C++的char*)
|
||
* @param pkey 密钥数组
|
||
* @param len 待解密的长度(-1表示使用整个数组长度)
|
||
* @param keyLength 密钥长度(默认5,与C++默认参数一致)
|
||
* @return 解密后的字节数组(原数组会被修改,同时返回新数组方便链式调用)
|
||
*/
|
||
public static byte[] cutecode(byte[] pstr, int[] pkey, int len, int keyLength) {
|
||
// 处理默认长度:如果len为-1,则使用数组的实际长度
|
||
if (len == -1) {
|
||
len = pstr.length;
|
||
}
|
||
// 遍历每个字节进行解密
|
||
for (int i = 0; i < len; i++) {
|
||
// 计算密钥索引,与C++逻辑一致
|
||
int keyIndex = i % keyLength;
|
||
int key2Index = (i + 18) % keyLength;
|
||
// 调用单个字符解密方法,修改原数组
|
||
pstr[i] = cutcodeChar(pstr[i], pkey[keyIndex], pkey[key2Index]);
|
||
}
|
||
return pstr;
|
||
}
|
||
|
||
// 重载方法:提供默认参数(对应C++的默认参数int keyLength = 5)
|
||
public static byte[] cutecode(byte[] pstr, int[] pkey, int len) {
|
||
return cutecode(pstr, pkey, len, 5);
|
||
}
|
||
|
||
// 重载方法:最简化调用(len=-1,keyLength=5)
|
||
public static byte[] cutecode(byte[] pstr, int[] pkey) {
|
||
return cutecode(pstr, pkey, -1, 5);
|
||
}
|
||
/**
|
||
* 压缩字符串
|
||
* @param input 原始字符串
|
||
* @return Base64编码后的压缩字符串(便于存储/传输)
|
||
*/
|
||
public static String compress(String input) {
|
||
if (input == null || input.isEmpty()) {
|
||
return input;
|
||
}
|
||
|
||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||
GZIPOutputStream gzipOS = new GZIPOutputStream(bos)) {
|
||
|
||
gzipOS.write(input.getBytes(StandardCharsets.UTF_8));
|
||
gzipOS.finish();
|
||
|
||
// 将压缩后的字节数组转为Base64字符串(避免二进制乱码)
|
||
byte[] compressedBytes = bos.toByteArray();
|
||
return java.util.Base64.getEncoder().encodeToString(compressedBytes);
|
||
|
||
} catch (IOException e) {
|
||
throw new RuntimeException("压缩失败", e);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 解压字符串
|
||
* @param compressedStr Base64编码后的压缩字符串
|
||
* @return 解压后的原始字符串
|
||
*/
|
||
public static String decompress(String compressedStr) {
|
||
if (compressedStr == null || compressedStr.isEmpty()) {
|
||
return compressedStr;
|
||
}
|
||
|
||
byte[] compressedBytes = java.util.Base64.getDecoder().decode(compressedStr);
|
||
System.out.println(Arrays.toString(compressedBytes));
|
||
try (ByteArrayInputStream bis = new ByteArrayInputStream(compressedBytes);
|
||
GZIPInputStream gzipIS = new GZIPInputStream(bis);
|
||
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||
|
||
byte[] buffer = new byte[1024];
|
||
int len;
|
||
while ((len = gzipIS.read(buffer)) != -1) {
|
||
bos.write(buffer, 0, len);
|
||
}
|
||
|
||
return new String(bos.toByteArray(), StandardCharsets.UTF_8);
|
||
|
||
} catch (IOException e) {
|
||
throw new RuntimeException("解压失败", e);
|
||
}
|
||
}
|
||
|
||
}
|