鉴于最终阻止未正确填充,加密问题

时间:2017-06-03 19:36:03

标签: java encryption aes

我是密码的新手,我总是得到这个错误

有一项服务:http://aesencryption.net/ 所以我加密了文本,以便将服务结果放入我的测试用例

key: passwd
original: mysecret
bytes: 128 (*don't know what it means but anyway..)
encrypted: EaDf/5rVXY3qMeQx1JmPCw==

我有这个scala代码

import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

import com.github.kondaurovdev.snippets.helper.{CryptoHelper, TryHelper}
import org.apache.commons.codec.binary.Base64

object Crypter {

  def apply(secret: String): Either[String, Crypter] = {
    for (
      s <- CryptoHelper.getSecretKey(secret).left.map(err => s"Can't get secretKeySpec: $err").right
    ) yield new Crypter(s)
  }

}

class Crypter(secretKey: SecretKeySpec) {

  def encrypt(input: String): Either[String, String] = {

    TryHelper.tryBlock({
      val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
      cipher.init(Cipher.ENCRYPT_MODE, secretKey)
      val encrypted = cipher.doFinal(input.getBytes("UTF-8"))
      Base64.encodeBase64String(encrypted)
    }, "Can't encrypt text")

  }

  //input = base64 encoded string
  def decrypt(input: String): Either[String, String] = {

    for (
      res <- {
        TryHelper.tryBlock({
          val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
          cipher.init(Cipher.DECRYPT_MODE, secretKey)
          val decrypted = cipher.doFinal(Base64.decodeBase64(input))
          new String(decrypted)
        }, "Error while decrypting")
      }.right
    ) yield res

  }


}

object CryptoHelper {

  def getSecretKey(myKey: String): Either[String, SecretKeySpec] = {
    TryHelper.tryBlock({
      var key = myKey.getBytes("UTF-8")
      val sha = MessageDigest.getInstance("SHA-1")
      key = sha.digest(key)
      key = util.Arrays.copyOf(key, 16) // use only first 128 bit
      new SecretKeySpec(key, "AES")
    }, "Can't build secretKey")
  }

}

object TryHelper {

  def tryBlock[R, E <: Throwable](block: => R, errPrefix: String = "", handle: errorPF = handlePF): Either[String, R] = {
    tryToEither(block).left.map(err => {
      var msg = err.getMessage
      if (errPrefix.nonEmpty) msg = s"$errPrefix: $msg"
      msg
    })
  }

}

我有这个测试用例:

import com.github.kondaurovdev.snippets.Crypter
import org.specs2.mutable.Specification

class CrypterSpec extends Specification {

  "Crypter" should {

    val crypter = Crypter("passwd")

    "decrypt" in {

      "case 1" in {
        crypter.right.flatMap(_.decrypt("eRKUj0EIXgyqzNFwHWYSLw==")) must beRight("asd")
      }

    }

    "encrypt" in {

      "case 1" in {
        crypter.right.flatMap(_.encrypt("asd")) must beRight("eRKUj0EIXgyqzNFwHWYSLw==")
      }

    }

  }

}

但这些测试没有通过......

> snippets/testOnly snippets.CrypterSpec
[info] CrypterSpec
[info] 
[info] Crypter should
[info]   decrypt
[error]     x case 1
[error]      'Left(Error while decrypting: Given final block not properly padded)' is not Right (CrypterSpec.scala:15)
[info] 
[info]   encrypt
[error]     x case 1
[error]      'Right(bVkPlx7E0OjhCWFyIHzM5Q==)' is Right but 'bVkPlx7E0OjhCWFyIHzM5Q==' is not equal to 'eRKUj0EIXgyqzNFwHWYSLw==' (CrypterSpec.scala:23)
[error] Actual:   bVkPlx7E0OjhCWFyIHzM5Q==
[error] Expected: eRKUj0EIXgyqzNFwHWYSLw==
[info] 
[info] 
[info] 
[info] Total for specification CrypterSpec
[info] Finished in 6 minutes 3 seconds, 588 ms
[info] 2 examples, 2 failures, 0 error
[info] 
[error] Failed: Total 2, Failed 2, Errors 0, Passed 0
[error] Failed tests:
[error]         snippets.CrypterSpec
[error] (snippets/test:testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 366 s, completed Jun 3, 2017 11:24:16 PM

1 个答案:

答案 0 :(得分:2)

由于我不是scala程序员,因此我将您的代码转换为我认为相当于Java代码的代码。加密“asd”的结果与您的匹配 - 输出为bVkPlx7E0OjhCWFyIHzM5Q==。因此,我得出结论,您期望输出应该是eRKUj0EIXgyqzNFwHWYSLw==是不正确的。

如果您使用的是您引用的测试结果网站,请注意他们可能没有使用相同的功能将字符串映射到AES密钥。将低熵串转换为对称密钥的推荐算法包括pbkdf2,bcrypt,scrypt等。这些是专门为这种情况设计的。