Skip to content

Instantly share code, notes, and snippets.

@Ksisu
Created May 18, 2018 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ksisu/da36ead2a76e150220a531a5296bf603 to your computer and use it in GitHub Desktop.
Save Ksisu/da36ead2a76e150220a531a5296bf603 to your computer and use it in GitHub Desktop.
Simple cryptor with AES GCM
import java.security.SecureRandom
import java.util.Base64
import javax.crypto.spec.{GCMParameterSpec, SecretKeySpec}
import javax.crypto.{Cipher, KeyGenerator, SecretKey}
object Cryptor {
def main(args: Array[String]): Unit = {
val cryptor = new Cryptor("84AmEdqF7YTruR2o4^2BfwkSA0weHtEVgHz$7Rqy".getBytes)
val messageToEncrypt = "🤐 Secret message 🤐"
val encryptedText = cryptor.encrypt(messageToEncrypt)
System.out.println("Encrypted Text1: " + encryptedText)
val decryptedText = cryptor.decrypt(encryptedText)
System.out.println("Decrypted text: " + decryptedText)
}
}
class Cryptor(private val secret: Array[Byte]) {
private val AES_KEY_SIZE = 256
private val AES_KEY_SIZE_IN_BYTE = AES_KEY_SIZE / 8
private val IV_SIZE = 128
private val TAG_BIT_LENGTH = 128
private val ALGO_TRANSFORMATION_STRING = "AES/GCM/PKCS5Padding"
private val ALGO = "AES"
private val secureRandom = new SecureRandom()
def encrypt(message: String): String = {
val aesKey: SecretKey = generateAesKey()
val gcmParameterSpec = generateGcmParameterSpec()
val cipher = Cipher.getInstance(ALGO_TRANSFORMATION_STRING)
cipher.init(Cipher.ENCRYPT_MODE, aesKey, gcmParameterSpec, new SecureRandom())
cipher.updateAAD(secret)
val encryptedMessage = cipher.doFinal(message.getBytes)
encodeData(aesKey, gcmParameterSpec, encryptedMessage)
}
def decrypt(encryptedDataString: String): String = {
val (aesKey, gcmParameterSpec, encryptedMessage) = decodeData(encryptedDataString)
val cipher = Cipher.getInstance(ALGO_TRANSFORMATION_STRING)
cipher.init(Cipher.DECRYPT_MODE, aesKey, gcmParameterSpec, new SecureRandom())
cipher.updateAAD(secret)
val message = cipher.doFinal(encryptedMessage)
new String(message)
}
private def generateAesKey(): SecretKey = {
val keygen = KeyGenerator.getInstance(ALGO)
keygen.init(AES_KEY_SIZE)
keygen.generateKey
}
private def generateGcmParameterSpec(): GCMParameterSpec = {
val iv = new Array[Byte](IV_SIZE)
secureRandom.nextBytes(iv)
new GCMParameterSpec(TAG_BIT_LENGTH, iv)
}
private def encodeData(aesKey: SecretKey, gcmParameterSpec: GCMParameterSpec, encryptedMessage: Array[Byte]): String = {
val data = aesKey.getEncoded ++ gcmParameterSpec.getIV ++ encryptedMessage
Base64.getEncoder.encodeToString(data)
}
private def decodeData(encodedData: String): (SecretKeySpec, GCMParameterSpec, Array[Byte]) = {
val data = Base64.getDecoder.decode(encodedData)
val aesKey = new SecretKeySpec(data.take(AES_KEY_SIZE_IN_BYTE), ALGO)
val iv = data.slice(AES_KEY_SIZE_IN_BYTE, AES_KEY_SIZE_IN_BYTE + IV_SIZE)
val gcmParameterSpec = new GCMParameterSpec(TAG_BIT_LENGTH, iv)
val encryptedMessage = data.drop(AES_KEY_SIZE_IN_BYTE + IV_SIZE)
(aesKey, gcmParameterSpec, encryptedMessage)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment