2017-06-03 86 views
1

我在密新手,我总是得到这个犯错鉴于最终块未正确填充,加密问题

有一个服务: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

我不知道scala,但是如果这是java,那么返回'new String(解密)'将是一个错误。你在加密时做的所有事情都必须在解密时完成,所以你应该返回'new String(解密的,“UTF-8”)'。但是,这不会导致BadPaddingException,所以我还没有看到那是什么。我可能会尝试重新创建一个Java代码版本,并看看会发生什么。 –

回答

2

因为我不是一个程序员阶我转换你的代码,我认为是等价的Java代码。我对加密“asd”的结果与您匹配 - 输出为bVkPlx7E0OjhCWFyIHzM5Q==。因此,我得出结论,你的期望输出应该是eRKUj0EIXgyqzNFwHWYSLw==是不正确的。

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

+0

当我更改bVkPlx7E0OjhCWFyIHzM5Q上的eRKUj0EIXgyqzNFwHWYSLw时,此错误消失,测试成功。你是对的,这都是因为我错误的期望。我只是将代码(从网站,看看网站的底部)转换为scala等值,并认为它应该工作。谢谢你的帮助。我想使用加密来加密配置文件中的密码,并在应用程序需要时解密它们 –

相关问题