使用random ivparameterspec,解密不起作用

xxhby3vn  于 2021-05-16  发布在  Spark
关注(0)|答案(0)|浏览(289)

尝试在spark中定义udf函数来加密/解密Dataframe中的列。我使用两个加密函数,其中一个使用随机ivparameterspec(iv)。我不清楚的是如何使用解密。我知道这是世界上最糟糕的事情使用固定静脉,并重复使用同一把钥匙的静脉。

val encryptUDF = udf((initVecText: String, key : String, text : String) => {
    val Algorithm = "AES/CBC/PKCS5Padding"
    val Key = new SecretKeySpec(Base64.getDecoder.decode(key), "AES")
    val IvSpec = new IvParameterSpec(initVecText.getBytes("UTF-8"))
    val cipher = Cipher.getInstance(Algorithm)
    cipher.init(Cipher.ENCRYPT_MODE, Key, IvSpec)
    new String(Base64.getEncoder.encode(cipher.doFinal(text.getBytes("utf-8"))), "utf-8")
})

val encryptUDF2 = udf((key : String, text : String) => {
    val Algorithm = "AES/CBC/PKCS5Padding"
    val Key = new SecretKeySpec(Base64.getDecoder.decode(key), "AES")
    val rand = new SecureRandom()
    val bytes = new Array[Byte](16)
    rand.nextBytes(bytes)
    val ivSpec = new IvParameterSpec(bytes)
    val cipher = Cipher.getInstance(Algorithm)
    cipher.init(Cipher.ENCRYPT_MODE, Key, ivSpec)
    new String(Base64.getEncoder.encode(cipher.doFinal(text.getBytes("utf-8"))), "utf-8")
})

val dencryptUDF = udf((initVector: String, key : String, text : String) => {
    val iv = new IvParameterSpec(initVector.getBytes("UTF-8"))
    val skeySpec = new SecretKeySpec(Base64.getDecoder.decode(key), "AES")
    val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv)
    val original = cipher.doFinal(Base64.getDecoder.decode(text))
    new String(original)
})

val dencryptUDF2 = udf((key : String, text : String) => {
    val rand = new SecureRandom()
    val bytes = new Array[Byte](16)
    rand.nextBytes(bytes)
    val iv = new IvParameterSpec(bytes)
    val skeySpec = new SecretKeySpec(Base64.getDecoder.decode(key), "AES")
    val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv)
    val original = cipher.doFinal(Base64.getDecoder.decode(text))
    new String(original)
})

示例(不是scala代码段):

text="417701467673"
key="YWFhYWJiYmJjY2NjZGRkZGVlZWVmZmZmZ2dnZ2hoaGg="
initVec1="InitVec_FAKEVEC1"
initVec2="InitVec_FAKEVEC2"

// encryption
CASE 1: encryptUDF(initVec1, key, text) => "h0iI8IWv4sCaEhMOdGU6pw==" // does not change if rerun twice
CASE 2: encryptUDF(initVec2, key, text) => "DVs9geuiNB2VPkwG1OSuTA==" // does not change if rerun twice
CASE 3: encryptUDF2(key, text)          => "3XTQwfjBN77GTMd5Xk2o3w==" // always a random output at each run

// decryption

// CASE 1:
dencryptUDF(initVec1, key, "h0iI8IWv4sCaEhMOdGU6pw==") => "417701467673" // OK, using the same IV
dencryptUDF(initVec2, key, "h0iI8IWv4sCaEhMOdGU6pw==") => "417701464673" // WRONG! using another IV (note it is a different number)
dencryptUDF2(key,          "h0iI8IWv4sCaEhMOdGU6pw==") => javax.crypto.BadPaddingException using a random IV

// CASE 2:
dencryptUDF(initVec1, key, "DVs9geuiNB2VPkwG1OSuTA==") => "417701467673" // WRONG! using another IV 
dencryptUDF(initVec2, key, "DVs9geuiNB2VPkwG1OSuTA==") => "417701464673" // OK, using the same IV
dencryptUDF2(key,          "DVs9geuiNB2VPkwG1OSuTA==") => javax.crypto.BadPaddingException using a random IV

// CASE 3:
dencryptUDF(initVec1, key, "3XTQwfjBN77GTMd5Xk2o3w==") => javax.crypto.BadPaddingException using initVec1
dencryptUDF(initVec2, key, "3XTQwfjBN77GTMd5Xk2o3w==") => javax.crypto.BadPaddingException using initVec2
dencryptUDF2(key,          "3XTQwfjBN77GTMd5Xk2o3w==") => javax.crypto.BadPaddingException using a random IV

例外情况:

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
  at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:989)
  at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
  at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
  at javax.crypto.Cipher.doFinal(Cipher.java:2165)
  at $anonfun$1.apply(<console>:76)
  at $anonfun$1.apply(<console>:71)
  ... 16 more

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题