2

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)'

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.