AES加密/解密Java => OpenSSL命令行工具

时间:2018-09-25 12:36:12

标签: java scala encryption openssl aes

使用AES/CBC/PKCS5Padding和IV f8/NeLsJ*s*vygV@作为openssl命令行工具,用于AES加密/解密的下一个Scala代码等效于什么:

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

给出下一个输出:

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

1 个答案:

答案 0 :(得分:0)

我们可以使用openssl with enc argument并将键和iv向量作为参数传递,以得到相同的结果。

初始步骤

  1. 获取用作密钥的字符串的十六进制表示形式。我们的密钥是abcde1234567890*。我们可以运行echo -n "abcde1234567890*" | od -A n -t x1 | tr -d ' '来获取6162636465313233343536373839302a的十六进制表示形式
  2. 获取用作IvParameter的字符串的十六进制表示形式。 IvParameter使用f8/NeLsJ*s*vygV@构建。我们可以运行echo -n "f8/NeLsJ*s*vygV@" | od -A n -t x1 | tr -d ' '给出66382f4e654c734a2a732a7679675640
  3. 从密钥长度得出算法。我们的密钥大小为16个字节或16 * 8 = 128位。所以是AES-128

加密: printf %s "Hello World" | openssl enc -e -aes-128-cbc -base64 -K 6162636465313233343536373839302a -iv 66382f4e654c734a2a732a7679675640以在Base64中获取加密的数据。它给出了f7YULyfM9wl/4tjNWvpwCQ==

解密: printf "%s\n" "f7YULyfM9wl/4tjNWvpwCQ==" | openssl enc -d -aes-128-cbc -base64 -K 6162636465313233343536373839302a -iv 66382f4e654c734a2a732a7679675640从Base64解密。它给出了Hello World