2017-06-03 89 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等值,並認爲它應該工作。謝謝你的幫助。我想使用加密來加密配置文件中的密碼,並在應用程序需要時解密它們 –

相關問題