Actually i have written an Hive UDF in Java for Encryption and Decryption. But it has some minor Bug in it. I couldn't find it, someone can Please rectify and suggest me some changes..
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
The cause is not related to the Hive.
The encrypted string is separated by CRLFs, so you should remove the \\r\\n
at the end of your encryption method: return new Text(EncText.toString().replaceAll("\\r|\\n", ""));
Thanks @Will Du, Your solution worked for me.
I've implemented this encryption code and ran in to a similar issue. Below change to the return line of Encrypt
method did the trick.
Before:
return output;
After:
return output.replaceAll("\r|\n", "");
I doubt your UDF evaluates return type Text . Change return type from Text to String as Hive supports following String types :
STRING
VARCHAR (Note: Only available starting with Hive 0.12.0)
CHAR (Note: Only available starting with Hive 0.13.0)
please check the Hive datatypes link
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.