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", "");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With