首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优化加密进程scala

如何优化加密进程scala
EN

Stack Overflow用户
提问于 2020-05-19 12:27:31
回答 1查看 44关注 0票数 0

我是Scala的新手。我已经写了一个代码,它首先从数据库中带来一些I,然后应用加密(AES),然后编码(JWT)。下面是我的代码:

代码语言:javascript
复制
    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秒内到达。如何对此进行优化?

EN

回答 1

Stack Overflow用户

发布于 2020-05-19 15:40:57

这样的事情

代码语言:javascript
复制
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 -它不安全,但在单元测试中,您测试的不是安全性,而是输出,因此您可以以更快但不太安全的方式计算它)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61883249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档