我是Scala的新手。我已经写了一个代码,它首先从数据库中带来一些I,然后应用加密(AES),然后编码(JWT)。下面是我的代码:
val stdMap = result.rows.map(row => (row.values.head, row.values(1), row.values(2)))
.groupBy(_._1)
.mapValues(stdRow => {
val stdName = stdRow.head._2
val isArchived = (stdRow.head._3 != "NULL") && stdRow.head._3.toBoolean
val value = System.currentTimeMillis()
var encryptedStd = Util.aesEncrypt(AppConfig.secretKey, AppConfig.aesPasswordKey, stdRow.head._1)
val encodedToken = Util.jwtEncodeString(encryptedStd)
Map(
"value" -> stdName.toJson,
"isArchived" -> JsBoolean(isArchived),
"eStdId" -> encodedToken.toJson
)}).toJson
def initCipher(secretKey : String, salt : String,mode : Int) : Cipher = {
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256)
val tmp = factory.generateSecret(spec)
val skeySpec = new SecretKeySpec(tmp.getEncoded(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
val random = new SecureRandom()
random.nextBytes(ivCode)
cipher.init(mode, skeySpec, new IvParameterSpec(ivCode))
cipher
}
def addIVToCipher(encrypted : Array[Byte]) : Array[Byte] = {
val cipherWithIv = new Array[Byte](ivCode.length + encrypted.length)
Array.copy(ivCode, 0, cipherWithIv, 0, ivCode.length)
Array.copy(encrypted, 0, cipherWithIv, ivCode.length, encrypted.length)
cipherWithIv
}
def aesEncrypt(secretKey: String, salt: String, value: String): String = {
val cipher = initCipher(secretKey, salt, Cipher.ENCRYPT_MODE)
val encr = cipher.doFinal(value.getBytes("utf-8"))
val cipherWithIv = addIVToCipher(encr)
Base64.encodeBase64String(cipherWithIv)
}
def jwtEncodeString(stdId: String): String = {
val value = System.currentTimeMillis()
val jwtClaim = JwtClaim(s"""{"data": "${stdId}", "time":"${value}"}""")
Jwt.encode(jwtClaim, AppConfig.secretKey, JwtAlgorithm.HS256)
}因此,如果我删除encryptedStd和encodedToken,响应将在大约200-300ms内到达,但如果我使用encryptedStd和encodedToken,响应将在大约19秒内到达。如何对此进行优化?
发布于 2020-05-19 15:40:57
这样的事情
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256)
val tmp = factory.generateSecret(spec)
val skeySpec = new SecretKeySpec(tmp.getEncoded(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
val random = new SecureRandom()可能会导致初始化成本过高。由于您在.mapValues中调用它,因此您可能会多次调用它。实际上,在.groupBy之后,集合中的元素数量是这个集合的两倍。
重用AppConfig.secretKey, AppConfig.aesPasswordKey表明这是完全不必要的。
因此,只需重构您的实用程序,通过从aesEncrypt中删除它来运行一次initCither代码即可。或者将Util转换为一个使用从AppConfig获取值的构造函数初始化的类,这样对于所有方法,密码都已经初始化,而不是每次都重新创建。这应该使您只需支付一次创建密码的成本。
(此外,出于测试目的,您可以使用Random而不是SecureRandom -它不安全,但在单元测试中,您测试的不是安全性,而是输出,因此您可以以更快但不太安全的方式计算它)。
https://stackoverflow.com/questions/61883249
复制相似问题