cloudroam
2025-02-14 2fce91b8c0faf1290d8a35ee022dab3cdbc28a54
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
package com.example.firstapp.utils
 
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
 
/**
 * SM4分组密码算法是我国自主设计的分组对称密码算法
 */
@Suppress("unused", "MemberVisibilityCanBePrivate")
object SM4Crypt {
 
    const val SM4_CBC_NOPADDING = "SM4/CBC/NoPadding"
    const val SM4_CBC_PKCS5 = "SM4/CBC/PKCS5Padding"
    const val SM4_CBC_PKCS7 = "SM4/CBC/PKCS7Padding"
    const val SM4_ECB_NOPADDING = "SM4/ECB/NoPadding"
    const val SM4_ECB_PKCS5 = "SM4/ECB/PKCS5Padding"
    const val SM4_ECB_PKCS7 = "SM4/ECB/PKCS7Padding"
    private val BC_PROVIDER = BouncyCastleProvider()
    private val SM4_CBC_IV = byteArrayOf(3, 5, 6, 9, 6, 9, 5, 9, 3, 5, 6, 9, 6, 9, 5, 9)
 
    /**
     * 获取随机密钥
     */
    fun createSM4Key(): ByteArray {
        val seed = ByteArray(16)
        val random = SecureRandom()
        random.nextBytes(seed)
        return seed
    }
 
    @JvmOverloads
    fun encrypt(source: ByteArray, key: ByteArray, mode: String = SM4_CBC_PKCS7, iv: ByteArray? = SM4_CBC_IV): ByteArray {
        return doSM4(true, source, key, mode, iv)
    }
 
    @JvmOverloads
    fun decrypt(source: ByteArray, key: ByteArray, mode: String = SM4_CBC_PKCS7, iv: ByteArray? = SM4_CBC_IV): ByteArray {
        return doSM4(false, source, key, mode, iv)
    }
 
    private fun doSM4(forEncryption: Boolean, source: ByteArray, key: ByteArray, mode: String, iv: ByteArray?): ByteArray {
        return try {
            val cryptMode = if (forEncryption) 1 else 2
            val sm4Key = SecretKeySpec(key, "SM4")
            val cipher = Cipher.getInstance(mode, BC_PROVIDER)
            if (iv == null) {
                cipher.init(cryptMode, sm4Key)
            } else {
                val ivParameterSpec = IvParameterSpec(iv)
                cipher.init(cryptMode, sm4Key, ivParameterSpec)
            }
            cipher.doFinal(source)
        } catch (var9: Exception) {
            var9.printStackTrace()
            ByteArray(0)
        }
    }
 
}