简体   繁体   中英

Hive Udf (Encryption and Decryption) in Java

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..

Problem:

 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

Code for Encryption :

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());        
}

}

Input:

Actual I/p Ex:    1      AAA
                  2      BBB

Encrypted O/p Ex:     1      fdfsvansjw=
                      NULL   NULL
                      2      adf4vandjw=
                      NULL   NULL

Code For Decryption :

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());        
}

}

Input:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM