Skip to content

Instantly share code, notes, and snippets.

@maowug
Created September 12, 2016 02:33
Show Gist options
  • Save maowug/4a5a3bb0188d02d0b690946edf4f7180 to your computer and use it in GitHub Desktop.
Save maowug/4a5a3bb0188d02d0b690946edf4f7180 to your computer and use it in GitHub Desktop.
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"))
)
}
}
@maowug
Copy link
Author

maowug commented Sep 12, 2016

better to inject appProvider: Provider[Application] to object Encryption

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment