Created
May 18, 2018 15:25
-
-
Save Ksisu/da36ead2a76e150220a531a5296bf603 to your computer and use it in GitHub Desktop.
Simple cryptor with AES GCM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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