实际上,我已经用java编写了一个用于加密和解密的HiveUDF。但它有一些小错误。我找不到了,有人可以帮我修改一下。。
问题:
When i tried to execute this code using Hive it is showing some 'Null' columns for each
row.
Encrypted Ex: 1 fdfsvansjw=
NULL NULL
2 adf4vandjw=
NULL NULL
Actually it has to be displayed without NULL Values.When i tried to decrypt the above
data it is adding Newline Character '/n' in place of Null.
Decrypted Ex: 1 AAA
/n /n
2 BBB
/n /n
加密代码:
package Encrypt;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
import java.security.*;
import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import javax.swing.JOptionPane;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public final class En1 extends UDF {
public Text evaluate(final Text s) throws Exception {
if (s == null) {
return null;
}
byte[] sharedvector = {
0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
};
String EncText = "";
byte[] keyArray = new byte[24];
byte[] temporaryKey;
String key = "developersnotedotcom";
byte[] toEncryptArray = null;
//try
// {
toEncryptArray = s.toString().getBytes("UTF-8");
MessageDigest m = MessageDigest.getInstance("MD5");
temporaryKey = m.digest(key.getBytes("UTF-8"));
if(temporaryKey.length < 24) // DESede require 24 byte length key
{
int index = 0;
for(int i=temporaryKey.length;i< 24;i++)
{
keyArray[i] = temporaryKey[index];
}
}
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyArray, "DESede"), new IvParameterSpec(sharedvector));
byte[] encrypted = c.doFinal(toEncryptArray);
EncText = Base64.encodeBase64String(encrypted);
// }
/* catch(NoSuchAlgorithmException | UnsupportedEncodingException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException NoEx)
{
//JOptionPane.showMessageDialog(null, NoEx);
System.out.println(NoEx);
System.exit(1);
}*/
return new Text(EncText.toString());
}
}
输入:
Actual I/p Ex: 1 AAA
2 BBB
Encrypted O/p Ex: 1 fdfsvansjw=
NULL NULL
2 adf4vandjw=
NULL NULL
解密代码:
package Encrypt;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.hive.ql.exec.FunctionTask;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public final class Dec1 extends UDF {
public Text evaluate(final Text s) {
if (s == null) {
return null;
}
byte[] sharedvector = {
0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
};
String RawText = "";
byte[] keyArray = new byte[24];
byte[] temporaryKey;
String key = "developersnotedotcom";
byte[] toEncryptArray = null;
try
{
MessageDigest m = MessageDigest.getInstance("MD5");
temporaryKey = m.digest(key.getBytes("UTF-8"));
if(temporaryKey.length < 24) // DESede require 24 byte length key
{
int index = 0;
for(int i=temporaryKey.length;i< 24;i++)
{
keyArray[i] = temporaryKey[index];
}
}
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyArray, "DESede"), new IvParameterSpec(sharedvector));
byte[] decrypted = c.doFinal(Base64.decodeBase64(s.toString()));
RawText = new String(decrypted, "UTF-8");
}
catch(Exception NoEx)
{
//JOptionPane.showMessageDialog(null, NoEx);
System.out.println(NoEx + "This is Udf error");
System.exit(1);
}
return new Text(RawText.toString());
}
}
输入:
Decrypted I/p Ex: 1 fdfsvansjw=
NULL NULL
2 adf4vandjw=
NULL NULL
Decrypted o/p Ex: 1 AAA
/n /n
2 BBB
/n /n
There should'nt be any Null's or /n when encryption and decryption.
Tried to find out the bug. But can't find out.
Please Help me.
Thanks
3条答案
按热度按时间rta7y2nd1#
原因与Hive无关。
加密字符串由crlfs分隔,因此应该删除
\r\n
在加密方法结束时:return new Text(EncText.toString().replaceAll("\r|\n", ""));
mepcadol2#
谢谢@will du,你的解决方案对我有用。
我已经实现了这个加密代码并遇到了类似的问题。以下是更改为
Encrypt
方法成功了。之前:
之后:
nwo49xxi3#
我怀疑你的自定义项评估返回类型文本。将返回类型从文本更改为字符串,因为配置单元支持以下字符串类型:
请检查配置单元数据类型链接