Artavazd Balayan
Artavazd Balayan

Reputation: 2413

AES Encryption/decryption Java => OpenSSL command line tool

What is an equivalent of next Scala code for AES encryption/decryption using AES/CBC/PKCS5Padding with IV f8/NeLsJ*s*vygV@ as openssl command line tool:

import java.nio.charset.StandardCharsets
import java.util.Base64

import javax.crypto.{BadPaddingException, Cipher}
import javax.crypto.spec.{IvParameterSpec, SecretKeySpec}

object AesCipher {
  private val algo: String = "AES"

  private val cipherCs: String = algo + "/CBC/PKCS5PADDING"

  private val iv: IvParameterSpec = new IvParameterSpec("f8/NeLsJ*s*vygV@".getBytes("UTF-8"))

  def encrypt(bytes: Array[Byte], secret: String): Array[Byte] = {
    val encrypter = Cipher.getInstance(cipherCs)
    val keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), algo)
    encrypter.init(Cipher.ENCRYPT_MODE, keySpec, iv)
    encrypter.doFinal(bytes)
  }

  def decrypt(bytes: Array[Byte], secret: String): Option[Array[Byte]] = {
    try {
      val decrypter = Cipher.getInstance(cipherCs)
      val keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), algo)
      decrypter.init(Cipher.DECRYPT_MODE, keySpec, iv)
      Some(decrypter.doFinal(bytes))
    }
    catch {
      case _: BadPaddingException => None
    }
  }

  def main(args: Array[String]): Unit = {
    val input = "Hello World"
    val secret = "abcde1234567890*"
    val inputBytes = input.getBytes(StandardCharsets.UTF_8)
    val encryptedBase64 = Base64.getEncoder.encodeToString(encrypt(inputBytes, secret))
    println(s"'$input' encrypted to '$encryptedBase64'")

    val decryptedStr = decrypt(Base64.getDecoder.decode(encryptedBase64), secret).map { bytes =>
      new String(bytes, StandardCharsets.UTF_8)
    }
    println(s"'$encryptedBase64' decrypted to '$decryptedStr'")
  }
}

It gives next output:

'Hello World' encrypted to 'f7YULyfM9wl/4tjNWvpwCQ=='
'f7YULyfM9wl/4tjNWvpwCQ==' decrypted to 'Some(Hello World)'

Upvotes: 2

Views: 3037

Answers (1)

Artavazd Balayan
Artavazd Balayan

Reputation: 2413

We can use openssl with enc argument and pass key and iv vector as a parameter to have the same result.

Initial steps:

  1. Get hex representation of the string which is used as secret key. Our key is abcde1234567890*. We can run echo -n "abcde1234567890*" | od -A n -t x1 | tr -d ' ' to get hex representation which is 6162636465313233343536373839302a
  2. Get hex representation of the string which is used as IvParameter. IvParameter is built using f8/NeLsJ*s*vygV@. We can run echo -n "f8/NeLsJ*s*vygV@" | od -A n -t x1 | tr -d ' ' gives 66382f4e654c734a2a732a7679675640
  3. Derive the algorithm from the key length. Our secret key size is 16 bytes or 16*8=128 bits. So it's AES-128

Encryption: printf %s "Hello World" | openssl enc -e -aes-128-cbc -base64 -K 6162636465313233343536373839302a -iv 66382f4e654c734a2a732a7679675640 to get encrypted data in Base64. It gives f7YULyfM9wl/4tjNWvpwCQ==

Decryption: printf "%s\n" "f7YULyfM9wl/4tjNWvpwCQ==" | openssl enc -d -aes-128-cbc -base64 -K 6162636465313233343536373839302a -iv 66382f4e654c734a2a732a7679675640 to decrypt from Base64. It gives Hello World

Upvotes: 4

Related Questions