尝试在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
暂无答案!
目前还没有任何答案,快来回答吧!