docs: 添加管理平台标准加密算法 Kotlin 参考实现
This commit is contained in:
115
docs/工具箱端-授权对接指南/utils/RsaOaepDecryptionUtil.kt
Normal file
115
docs/工具箱端-授权对接指南/utils/RsaOaepDecryptionUtil.kt
Normal file
@@ -0,0 +1,115 @@
|
||||
package top.tangyh.lamp.filing.utils
|
||||
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.stereotype.Component
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.KeyFactory
|
||||
import java.security.PublicKey
|
||||
import java.security.spec.PKCS8EncodedKeySpec
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
import java.util.*
|
||||
import javax.crypto.Cipher
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
/**
|
||||
* RSA-OAEP 解密工具类
|
||||
* 用于设备身份首次绑定时解密设备信息
|
||||
*
|
||||
* 使用场景:设备使用平台的公钥加密数据,平台使用私钥解密
|
||||
*/
|
||||
@Component
|
||||
class RsaOaepDecryptionUtil(
|
||||
@Value("\${device.encrypt.privateKey:}")
|
||||
private val privateKeyBase64: String
|
||||
) {
|
||||
|
||||
private val keyFactory = KeyFactory.getInstance("RSA")
|
||||
private val cipherAlgorithm = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"
|
||||
|
||||
// 缓存私钥,避免每次解密都重新加载
|
||||
private val privateKey by lazy {
|
||||
if (privateKeyBase64.isBlank()) {
|
||||
throw IllegalStateException("RSA私钥未配置,无法解密设备信息")
|
||||
}
|
||||
val privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64)
|
||||
val keySpec = PKCS8EncodedKeySpec(privateKeyBytes)
|
||||
keyFactory.generatePrivate(keySpec)
|
||||
}
|
||||
|
||||
init {
|
||||
if (privateKeyBase64.isBlank()) {
|
||||
logger.warn { "RSA私钥未配置,设备授权解密功能可能无法使用" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用RSA-OAEP解密设备信息
|
||||
* @param encryptedData Base64编码的加密数据
|
||||
* @return 解密后的JSON字符串
|
||||
*/
|
||||
fun decrypt(encryptedData: String): String {
|
||||
if (privateKeyBase64.isBlank()) {
|
||||
throw IllegalStateException("RSA私钥未配置,无法解密设备信息")
|
||||
}
|
||||
|
||||
return try {
|
||||
// 创建新的Cipher实例(Cipher不是线程安全的)
|
||||
val cipher = Cipher.getInstance(cipherAlgorithm)
|
||||
|
||||
// 初始化解密器
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey)
|
||||
|
||||
// Base64解码加密数据
|
||||
val encryptedBytes = Base64.getDecoder().decode(encryptedData)
|
||||
|
||||
// 解密数据
|
||||
val decryptedBytes = cipher.doFinal(encryptedBytes)
|
||||
|
||||
// 返回解密后的字符串
|
||||
String(decryptedBytes, StandardCharsets.UTF_8)
|
||||
} catch (e: Exception) {
|
||||
logger.error(e) { "RSA-OAEP解密设备信息失败" }
|
||||
throw RuntimeException("RSA-OAEP解密设备信息失败: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用平台公钥加密数据
|
||||
*
|
||||
* @param plainText 原始JSON字符串(设备信息)
|
||||
* @param publicKeyBase64 平台公钥(Base64)
|
||||
* @return Base64编码的密文
|
||||
*/
|
||||
fun encrypt1(
|
||||
plainText: String,
|
||||
publicKeyBase64: String
|
||||
): String {
|
||||
try {
|
||||
val publicKey = loadPublicKey(publicKeyBase64)
|
||||
|
||||
val cipher = Cipher.getInstance(cipherAlgorithm)
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
|
||||
|
||||
val encryptedBytes = cipher.doFinal(
|
||||
plainText.toByteArray(StandardCharsets.UTF_8)
|
||||
)
|
||||
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes)
|
||||
} catch (e: Exception) {
|
||||
logger.error(e) { "RSA-OAEP 加密失败" }
|
||||
throw RuntimeException("RSA-OAEP 加密失败: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadPublicKey(base64Key: String): PublicKey {
|
||||
val keyBytes = Base64.getDecoder().decode(base64Key)
|
||||
val keySpec = X509EncodedKeySpec(keyBytes)
|
||||
return keyFactory.generatePublic(keySpec)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user