u.go
2016-09-12T02:33:44Z

Encryption.scala

|
| trait Encryption {
|
| /**
| * Encrypt token
| * @param app
| * @param token
| * @return
| */
| def encryptToken(app: Application, token: String): String = {
| val (key, salt) = getKeyAndSaltFromConf(app)
| encrypt(key, token, salt)
| }
|
| /**
| * Decrypt token
| * when decrypt failed: ignore invalid token format since can't get from cache anyway
| * @param app
| * @param token
| * @return
| */
| def decryptToken(app: Application, token: String): String = {
| val (key, salt) = getKeyAndSaltFromConf(app)
| try {
| decrypt(key, token, salt)
| } catch {
| case NonFatal(e) => token
| }
| }
|
| private[this] def encrypt(key: String, value: String, salt: String): String = {
| val cipher: Cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
| cipher.init(Cipher.ENCRYPT_MODE, keyToSpec(salt, key))
| Base64.encodeBase64String(cipher.doFinal(value.getBytes("UTF-8")))
| }
|
| private[this]def decrypt(key: String, encryptedValue: String, salt: String): String = {
| val cipher: Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING")
| cipher.init(Cipher.DECRYPT_MODE, keyToSpec(salt, key))
| new String(cipher.doFinal(Base64.decodeBase64(encryptedValue)))
| }
|
| private[this] def keyToSpec(salt:String, key: String): SecretKeySpec = {
| var keyBytes: Array[Byte] = (salt + key).getBytes("UTF-8")
| val sha: MessageDigest = MessageDigest.getInstance("SHA-1")
| keyBytes = sha.digest(keyBytes)
| keyBytes = util.Arrays.copyOf(keyBytes, 16)
| new SecretKeySpec(keyBytes, "AES")
| }
|
| private[this] def getKeyAndSaltFromConf(app: Application) :(String, String) = {
| (app.configuration.getString("play.http.token.key")
| .getOrElse(throw new Exception("token key undefined")),
| app.configuration.getString("play.http.token.salt")
| .getOrElse(throw new Exception("token salt undefined"))
| )
| }
|
| }