rain
2024-08-20 74d1c21ebb6b3b916904d95d13d289df23dcdedd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.dji.sample.droneairport.utils;
 
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
 
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
 
public class SM4Util {
 
 
    /**
     * 生成一个随机的SM4加密密钥。
     *
     * SM4算法是一种对称加密算法,其密钥长度为128位(16字节)。
     * 本方法使用安全随机数生成器生成一个16字节的随机值作为SM4密钥,
     * 并将其转换为十六进制字符串格式以便于使用和存储。
     *
     * @return 返回一个表示SM4密钥的十六进制字符串。
     */
    public static String generateSM4Key() {
        SecureRandom secureRandom = new SecureRandom();
        byte[] sm4Key = new byte[8]; // SM4 密钥长度为 128 位(16 字节)
        secureRandom.nextBytes(sm4Key);
        String key = bytesToHex(sm4Key);
        return key;
    }
 
 
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
    /**
     * 使用SM4算法加密输入数据。
     *
     * @param key 加密密钥,应符合SM4算法的密钥长度要求。
     * @param input 待加密的输入数据。
     * @return 加密后的数据,以Base64编码形式表示。
     */
    public static String encrypt(byte[] key, byte[] input) {
        // 创建并初始化SM4加密器
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SM4Engine(), new PKCS7Padding());
        cipher.init(true, new KeyParameter(key));  // ECB模式下不需要IV
 
        // 用于存储加密后的数据
        byte[] output = new byte[cipher.getOutputSize(input.length)];
        // 处理输入数据,进行加密
        int length = cipher.processBytes(input, 0, input.length, output, 0);
 
        // 完成加密过程,处理可能剩余的数据
        try {
            length += cipher.doFinal(output, length);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        // 使用Base64编码加密后的字节数组,并返回
        String encoded = Base64.getEncoder().encodeToString(Arrays.copyOf(output, length));
        return encoded;
    }
 
 
    /**
     * 使用SM4算法对输入数据进行解密
     *
     * @param key 密钥字节数组,用于解密数据
     * @param input 待解密的字节数组
     * @return 解密后的字节数组
     */
    public static byte[] decrypt(byte[] key, byte[] input) {
        // 创建基于SM4算法的缓冲分组密码对象
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new SM4Engine(), new PKCS7Padding());
        // 初始化密码对象为解密模式,并设置密钥参数
        cipher.init(false, new KeyParameter(key));  // ECB模式下不需要IV
        // 根据输入数据长度计算解密后的字节数组长度
        byte[] output = new byte[cipher.getOutputSize(input.length)];
        // 处理字节数组,将输入数据解密到输出字节数组中
        int length = cipher.processBytes(input, 0, input.length, output, 0);
        try {
            // 完成最终的解密操作,并将长度累加到已处理字节数组中
            length += cipher.doFinal(output, length);
        } catch (Exception e) {
            // 捕获并处理解密过程中的异常
            e.printStackTrace();
        }
        // 返回解密后的字节数组
        return Arrays.copyOf(output, length);
    }
 
    public static String decrypt(String keys,String secert){
        byte[] key = keys.getBytes(StandardCharsets.UTF_8);
        byte[] ming= Base64.getDecoder().decode(secert);
        byte[] text=decrypt(key,ming);
        return new String(text, StandardCharsets.UTF_8);
    }
 
    public static String encrypt(String keys, String input){
        byte[] key = keys.getBytes(StandardCharsets.UTF_8);
        return encrypt(key,input.getBytes());
    }
 
    public static void main(String[] args) {
        System.out.println(generateSM4Key());
        byte[] key = "2bc304ccba171672".getBytes(StandardCharsets.UTF_8); // 16字节密钥
 
        // 原始明文
        String plaintext = "{\n" +
                "  \"deviceid\": [\n" +
                "    \"1581F6QAD241800B6V95\",\n" +
                "    \"1581F6QAD241500BDZ3J\"\n" +
                "  ],\n" +
                "  \"bizidname\": \"test\",\n" +
                "  \"tasklist\": [\n" +
                "    {\n" +
                "      \"bsm\": \"20281071717177177\",\n" +
                "      \"xzqdm\": \"31000\",\n" +
                "      \"dkbh\": \"ndbg20110210711\",\n" +
                "      \"dklx\": \"ndbg2774\",\n" +
                "      \"dkmc\": \"桥头\",\n" +
                "      \"dkmj\": 20.574,\n" +
                "      \"dkfw\": \"POLYGON((116.0216 25.8926,116.0217 25.8921,116.0205 25.8919,116.0204 25.8928,116.0214 25.8931,116.0216 25.8926))\"\n" +
                "    }  ]\n" +
                "}";
        String secert =encrypt(key,plaintext.getBytes());
//        System.out.println(secert);
 
 
        byte[] ming= Base64.getDecoder().decode(secert);
        byte[] text=decrypt(key,ming);
//        System.out.println(new String(text, StandardCharsets.UTF_8));
        System.out.println(encrypt("2bc304ccba171672",plaintext));
//        System.out.println(generateSM4Key());
//        System.out.println("封装"+decrypt("8a217699714b0fc0","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"));
        String encryptedBase64 = encrypt(key, plaintext.getBytes(StandardCharsets.UTF_8));
//        System.out.println("Encrypted (Base64): " + encryptedBase64);
//        System.out.println(generateSM4Key());
        // 直接解密
        byte[] decoded = Base64.getDecoder().decode(encryptedBase64);
        byte[] decrypted = decrypt(key, decoded);
 
//        // 输出结果
//        System.out.println("Plaintext: " + plaintext);
//        System.out.println("Decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
    }
}