This commit is contained in:
2026-09-24 16:25:22 +08:00
commit 7428184f01
1198 changed files with 314515 additions and 0 deletions
@@ -0,0 +1,393 @@
package uts.sdk.modules.utsXcryptoS
import java.security.*
import java.security.spec.X509EncodedKeySpec
import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.*
import javax.crypto.spec.SecretKeySpec
import javax.crypto.spec.IvParameterSpec
import android.util.Base64
import java.nio.charset.Charset
import io.dcloud.uts.console
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.spec.RSAKeyGenParameterSpec
import java.security.KeyFactory
// 定义支持的输出长度枚举
enum class OutputLength(val length: Int) {
LENGTH_16(8), // 8 bytes = 16 hex chars
LENGTH_32(16), // 16 bytes = 32 hex chars
LENGTH_64(32) // 32 bytes = 64 hex chars
}
data class RSARandomKey(val publicKey: String, val privateKey: String)
class UniversalCryptoHelper {
companion object {
// MD5 Encryption ,32位加密
fun md5(input: String): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(input.toByteArray())
return digest.joinToString("") { "%02x".format(it) }
}
// BASE64 Encoding and Decoding
fun base64Encode(input: String): String = Base64.encodeToString(input.toByteArray(), android.util.Base64.NO_WRAP)
fun base64Decode(input: String): String = String(Base64.decode(input, Base64.DEFAULT))
// HMAC with SHA-256
fun hmacSha256(key: String, data: String): String {
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
val mac = Mac.getInstance("HmacSHA256")
mac.init(secretKey)
val hash = mac.doFinal(data.toByteArray())
return hash.joinToString("") { "%02x".format(it) }
}
// SHA-1 and SHA-256 Hashing
fun sha1(input: String): String {
val md = MessageDigest.getInstance("SHA-1")
val digest = md.digest(input.toByteArray())
return digest.joinToString("") { "%02x".format(it) }
}
fun sha256(input: String): String {
val md = MessageDigest.getInstance("SHA-256")
val digest = md.digest(input.toByteArray())
return digest.joinToString("") { "%02x".format(it) }
}
/**
* 计算SHA-512哈希值
* @param input 需要计算哈希的字符串
* @return 哈希值的十六进制字符串
*/
fun sha512(input: String): String {
val md = MessageDigest.getInstance("SHA-512")
val digest = md.digest(input.toByteArray())
return digest.joinToString("") { "%02x".format(it) }
}
/**
* 使用HMAC-SHA512算法计算消息认证码
* @param key 密钥
* @param data 需要认证的数据
* @return HMAC值的十六进制字符串
*/
fun hmacSha512(key: String, data: String): String {
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA512")
val mac = Mac.getInstance("HmacSHA512")
mac.init(secretKey)
val hmacBytes = mac.doFinal(data.toByteArray())
return hmacBytes.joinToString("") { "%02x".format(it) }
}
fun generateAesKey(key: String, keySize: Int = 16): ByteArray {
val fixedKey = key.padEnd(keySize, '0') // 填充到 16 字节(128 位)
return fixedKey.toByteArray().copyOf(keySize) // 截断或扩展为 16 字节
}
fun generateDesKey(key: String,keySize: Int = 24): ByteArray {
// 确保密钥长度为24字节,不足时用0填充,过长时截断
val keyBytes = key.toByteArray()
val paddedKey = ByteArray(keySize)
if (keyBytes.size < keySize) {
System.arraycopy(keyBytes, 0, paddedKey, 0, keyBytes.size)
} else {
System.arraycopy(keyBytes, 0, paddedKey, 0, keySize)
}
return paddedKey
}
fun generateDesKey2(key: ByteArray,keySize: Int = 24): ByteArray {
// 确保密钥长度为24字节,不足时用0填充,过长时截断
val keyBytes = key
val paddedKey = ByteArray(keySize)
if (keyBytes.size < keySize) {
System.arraycopy(keyBytes, 0, paddedKey, 0, keyBytes.size)
} else {
System.arraycopy(keyBytes, 0, paddedKey, 0, keySize)
}
return paddedKey
}
/**
* 返回编码为base64,cbc或者ecb,填充这pkcs5/pkdcs7,密钥和iv偏移均为16位
*/
fun aesEncrypt(input: String, key: String,mode:String,iv: String? = null,keySize:Int?=16): String {
if(mode=="ECB"){
val secretKey = SecretKeySpec(generateDesKey(key,keySize?:16), "AES")
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val encrypted = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypted, Base64.NO_WRAP)
}
// cbc
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val keySpec = SecretKeySpec(generateDesKey(key,keySize?:16), "AES")
val ivSpecBz = generateDesKey(iv?:"",16)
val ivSpec = IvParameterSpec(ivSpecBz)
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
val encrypted = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypted, Base64.NO_WRAP)
}
fun aesEncrypt2(input: ByteArray, key: ByteArray,mode:String,iv: ByteArray? = null,keySize:Int?=16): ByteArray {
if(mode=="ECB"){
val secretKey = SecretKeySpec(generateDesKey2(key,keySize?:16), "AES")
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val encrypted = cipher.doFinal(input)
return encrypted
}
// cbc
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val keySpec = SecretKeySpec(generateDesKey2(key,keySize?:16), "AES")
val ivSpecBz = generateDesKey2(iv?:ByteArray(keySize?:16),16)
val ivSpec = IvParameterSpec(ivSpecBz)
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
val encrypted = cipher.doFinal(input)
return encrypted
}
/**
* 加密文本为base64,cbc或者ecb,填充这pkcs5/pkdcs7,密钥和iv偏移均为16位,返回字符串.
*/
fun aesDecrypt(input: String, key: String,mode:String,iv: String? = null,keySize:Int?=16): String {
if(mode=="ECB"){
val secretKey = SecretKeySpec(generateDesKey(key,keySize?:16), "AES")
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val decrypted = cipher.doFinal(Base64.decode(input, Base64.DEFAULT))
return String(decrypted)
}
// cbc
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val keySpec = SecretKeySpec(generateDesKey(key,keySize?:16), "AES")
// val ivSpec = adjustIV(iv?:"":iv,keySize?:16)
// val ivSpec = IvParameterSpec(iv!!.toByteArray())
val ivSpecBz = generateDesKey(iv?:"",16)
val ivSpec = IvParameterSpec(ivSpecBz)
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec)
val decodedBytes = Base64.decode(input, Base64.DEFAULT)
val decrypted = cipher.doFinal(decodedBytes)
return String(decrypted)
}
fun aesDecrypt2(input: ByteArray, key: ByteArray,mode:String,iv: ByteArray? = null,keySize:Int?=16): ByteArray {
if(mode=="ECB"){
val secretKey = SecretKeySpec(generateDesKey2(key,keySize?:16), "AES")
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val decrypted = cipher.doFinal(input)
// val decrypted = cipher.doFinal(Base64.decode(input, Base64.DEFAULT))
return decrypted
}
// cbc
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val keySpec = SecretKeySpec(generateDesKey2(key,keySize?:16), "AES")
// val ivSpec = adjustIV(iv?:"":iv,keySize?:16)
// val ivSpec = IvParameterSpec(iv!!.toByteArray())
val ivSpecBz = generateDesKey2(iv?:ByteArray(keySize?:16),16)
val ivSpec = IvParameterSpec(ivSpecBz)
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec)
// val decodedBytes = Base64.decode(input, Base64.DEFAULT)
val decrypted = cipher.doFinal(input)
return decrypted
}
// DES Encryption and Decryption
fun desEncrypt(input: String, key: String,mode:String,iv: String? = null): String {
val secretKey = SecretKeySpec(generateDesKey(key), "DESede")
val cipher: Cipher = when (mode) {
"ECB" -> Cipher.getInstance("DESede/ECB/PKCS5Padding")
"CBC" -> Cipher.getInstance("DESede/CBC/PKCS5Padding")
else -> throw IllegalArgumentException("Unsupported mode: $mode")
}
if (mode == "CBC" && iv == null) {
throw IllegalArgumentException("IV must not be null for CBC mode")
}
if (mode == "CBC") {
val ivSpec = IvParameterSpec(iv!!.toByteArray())
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec)
} else {
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
}
val encrypted = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypted, android.util.Base64.NO_WRAP)
}
fun desDecrypt(input: String, key: String,mode:String,iv: String? = null): String {
val secretKey = SecretKeySpec(generateDesKey(key), "DESede")
val cipher: Cipher = when (mode) {
"ECB" -> Cipher.getInstance("DESede/ECB/PKCS5Padding")
"CBC" -> Cipher.getInstance("DESede/CBC/PKCS5Padding")
else -> throw IllegalArgumentException("Unsupported mode: $mode")
}
if (mode == "CBC" && iv == null) {
throw IllegalArgumentException("IV must not be null for CBC mode")
}
if (mode == "CBC") {
val ivSpec = IvParameterSpec(iv!!.toByteArray())
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec)
} else {
cipher.init(Cipher.DECRYPT_MODE, secretKey)
}
val decrypted = cipher.doFinal(Base64.decode(input, Base64.DEFAULT))
return String(decrypted)
}
// Convert String to PublicKey
fun stringToPublicKey(publicKeyStr: String): PublicKey {
val keyBytes = Base64
.decode(publicKeyStr.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", "")
, Base64.DEFAULT
)
val keySpec = X509EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance("RSA")
return keyFactory.generatePublic(keySpec)
}
// Convert String to PrivateKey
fun stringToPrivateKey(privateKeyStr: String): PrivateKey {
val keyBytes = Base64.decode(privateKeyStr.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", "")
, Base64.DEFAULT
)
val keySpec = PKCS8EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance("RSA")
return keyFactory.generatePrivate(keySpec)
}
fun generateRSAKeyPair(keySize: Int = 2048): RSARandomKey {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(RSAKeyGenParameterSpec(keySize, RSAKeyGenParameterSpec.F4))
val keyPair: KeyPair = keyPairGenerator.generateKeyPair()
// 将公钥转换为X.509格式
val x509EncodedPublicKey = keyPair.public.encoded
val publicKeyString = Base64.encodeToString(x509EncodedPublicKey, Base64.NO_WRAP)
// 将私钥转换为PKCS#8格式
val pkcs8EncodedPrivateKey = keyPair.private.encoded
val privateKeyString = Base64.encodeToString(pkcs8EncodedPrivateKey, Base64.NO_WRAP)
return RSARandomKey(publicKeyString, privateKeyString)
}
// 默认是PKCS1,填充:(OAEPRSA/ECB/OAEPWithSHA-1AndMGF1Padding或者(PKCS1RSA/ECB/PKCS1Padding
fun rsaEncrypt(input: String, publicKeyStr: String): String {
val publicKey = stringToPublicKey(publicKeyStr)
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val encrypted = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypted, Base64.NO_WRAP)
}
// input是base64,PKCS1填充生成的加密内容
fun rsaDecrypt(input: String, privateKeyStr: String): String {
val privateKey = stringToPrivateKey(privateKeyStr)
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val decrypted = cipher.doFinal(Base64.decode(input, Base64.DEFAULT))
return String(decrypted)
}
fun rc4Init(key: ByteArray): ByteArray {
val s = ByteArray(256) { it.toByte() }
var j = 0
for (i in 0..255) {
j = (j + s[i].toInt() + key[i % key.size].toInt() and 0xFF) and 0xFF
val temp = s[i]
s[i] = s[j]
s[j] = temp
}
return s
}
fun rc4Process(data: ByteArray, key: ByteArray, outputLength: OutputLength): ByteArray {
val s = rc4Init(key)
val result = ByteArray(outputLength.length) // 使用指定的字节长度
var i = 0
var j = 0
for (n in result.indices) {
i = (i + 1) and 0xFF
j = (j + s[i].toInt() and 0xFF) and 0xFF
val temp = s[i]
s[i] = s[j]
s[j] = temp
val t = (s[i].toInt() + s[j].toInt() and 0xFF) and 0xFF
val k = s[t].toInt() and 0xFF
result[n] = if (n < data.size) {
(data[n].toInt() xor k).toByte()
} else {
k.toByte()
}
}
return result
}
//输出是hex字符串,密钥是8位字符
fun rc4Encrypt(data: String, key: String): String {
val dataBytes = data.toByteArray()
val keyBytes = key.toByteArray()
val encrypted = rc4Process(dataBytes, keyBytes, OutputLength.LENGTH_16)
return encrypted.joinToString("") { "%02x".format(it) }
}
//输入encryptedHex是hex字符串,返回是string,密钥是8位字符
fun rc4Decrypt(encryptedHex: String, key: String): String {
val encryptedBytes = encryptedHex.chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
val keyBytes = key.toByteArray()
val decrypted = rc4Process(encryptedBytes, keyBytes, OutputLength.LENGTH_16)
return decrypted.toString(Charset.defaultCharset()).trim('\u0000')
}
}
}