hive的自定义函数SM3加密20220306
显示内置的函数
show functions;
创建自定义函数的步骤(这个属于临时函数)
第一步:写Java代码,在pom文件中引入Hadoop和hive的相关依赖
第二步:写自定义函数,需要继承UDF函数,重载evaluate这个方法
package com.wzx.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class TestUdf extends UDF {public String evaluate(String s){if(null!=s){return s.toLowerCase();}return null;}}
第三步:把工程打成jar包放到服务器上,然后加载jar包到hive的lib下的路径
hive> add jar /root/lower.jar;
Added [/root/lower.jar] to class path
Added resources: [/root/lower.jar]
第四步:创建函数的名称,需要加上这个类的全路径名称
create temporary function tolowercase as 'com.wzx.udf.TestUdf';
第五步:可以用这个函数了
select tolowercase('ABCD') from dual;
注意:这个函数只在当前窗口中有效,在不同的库中也有效,只要换了窗口就失效了
CDH集群中需要的代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>udf</groupId><artifactId>udf</artifactId><version>1.0-SNAPSHOT</version><!-- 根据要连接的hadoop和hive,设置版本参数 --><properties><hadoop.version>2.6.0-cdh5.13.1</hadoop.version><hive.version>1.1.0-cdh5.13.1</hive.version></properties><!-- 因为使用CDH的hadoop和hive,因此要添加CDH的官方repository,才能够下载相应的依赖包 --><!-- 如果使用Apache版本的hadoop和hive,则不需要添加该repository --><repositories><repository><id>cloudera</id><url>http://repository.cloudera.com/artifactory/cloudera-repos</url></repository></repositories><dependencies><!-- 添加依赖组件,根据上方配置的版本参数和repository知识库下载依赖 --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>${hive.version}</version></dependency><!-- junit是java的单元测试框架 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency></dependencies></project>
hive中创建永久函数 SM3加密
第一步:把写好的UDF函数的代码打包放到集群上
package com.wzx.udf;
import com.jcraft.jsch.Cipher;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Arrays;
public class Sm3UDF extends UDF {/*** 传入的是两个参数* cph:车牌号码* key:加密的key*/public String evaluate ( String cph , String key) throws Exception {//判断车牌号码不能为空if (cph == null || "".equals(cph)){return "cph 不能为空";}//判断key不能为空if (key == null || "".equals(key)){return "key 不能为空";}//使用SM3进行加密encryptPlusString cph_secret = encryptPlus(cph, key);//返回加密后的车牌号码return cph_secret;}private static final String ENCODING = "UTF-8";static {//Security.addProvider(new BouncyCastleProvider());Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());}/*Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8"), "AES"));cipher.doFinal("QWEASDZS".getBytes("UTF-8"));*/public static void main(String[] args) {String aa = encryptPlus("1", "aa");System.out.println(aa);System.out.println(aa.length());}/*** sm3算法加密* @explain* @param paramStr* 待加密字符串* @return 返回加密后,固定长度=32的16进制字符串*//*** 返回长度=32的byte数组* @explain 生成对应的hash值* @param srcData* @return*/public static byte[] hash(byte[] srcData) {SM3Digest digest = new SM3Digest();//update the message digest with a single byte.digest.update(srcData, 0, srcData.length);byte[] hash = new byte[digest.getDigestSize()];//close the digest, producing the final digest value.digest.doFinal(hash, 0);return hash;}/*** sm3算法加密* @explain* @param paramStr* 待加密字符串* @param key* 密钥* @return 返回加密后,固定长度=32的16进制字符串*/public static String encryptPlus(String paramStr,String key){// 将返回的hash值转换成16进制字符串String resultHexString = "";try {// 将字符串转换成byte数组byte[] srcData = paramStr.getBytes(ENCODING);// 调用hash()byte[] resultHash = hmac(srcData,key.getBytes(ENCODING));// 将返回的hash值转换成16进制字符串resultHexString = ByteUtils.toHexString(resultHash);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return resultHexString;}/*** 通过密钥进行加密* @explain 指定密钥进行加密* @param key* 密钥* @param srcData* 被加密的byte数组* @return*/public static byte[] hmac(byte[] key, byte[] srcData) {KeyParameter keyParameter = new KeyParameter(key);SM3Digest digest = new SM3Digest();HMac mac = new HMac(digest);mac.init(keyParameter);mac.update(srcData, 0, srcData.length);byte[] result = new byte[mac.getMacSize()];mac.doFinal(result, 0);return result;}/*** 判断源数据与加密数据是否一致* @explain 通过验证原数组和生成的hash数组是否为同一数组,验证2者是否为同一数据* @param srcStr* 原字符串* @param sm3HexString* 16进制字符串* @return 校验结果*/public static boolean verify(String srcStr, String sm3HexString) {boolean flag = false;try {//使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中byte[] srcData = srcStr.getBytes(ENCODING);//16进制 --> byte[]byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);byte[] newHash = hash(srcData);//判断数组是否相等if (Arrays.equals(newHash, sm3Hash)) {flag = true;}} catch (UnsupportedEncodingException e) {e.printStackTrace();}return flag;}
/***********************使用Hutool工具类*****************************************************************************************//*** sm3算法加密** @param paramStr 待加密字符串* @return 返回加密后,固定长度=32的16进制字符串* @explain*//*** 判断源数据与加密数据是否一致(Hutool)** @param srcStr 原字符串* @param sm3HexString 16进制字符串* @return 校验结果*//***********************使用Hutool工具类*****************************************************************************************/}
pom文件中的代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.itcast.Mapreduce</groupId><artifactId>MyWordCount</artifactId><version>1.0</version><dependencies><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.6.4</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.6.4</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.6.4</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-core</artifactId><version>2.6.4</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>1.2.2</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><!--<version>5.0.3</version>--><version>5.7.7</version></dependency><!--<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.59</version></dependency>--><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.59</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.59</version></dependency><!-- 2022/01/02解决Maven工程中报 Missing artifact jdk.tools:jdk.tools: --><dependency><groupId>jdk.tools</groupId><artifactId>jdk.tools</artifactId><version>1.8</version><scope>system</scope><systemPath>${JAVA_HOME}/lib/tools.jar</systemPath></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><!-- 这里面是主类的全路径 --><mainClass>com.wzx.mapreduce.WordCountDriver</mainClass></manifest></archive></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>7</source><target>7</target></configuration></plugin></plugins></build></project>
第二步:把打包好的jar包上传到HDFS上
hadoop fs -put sm3.jar /user/hive/lib/
第三步:打开hive的客户端,创建函数
create function sm as 'com.wzx.udf.Sm3UDF' using jar 'hdfs:///user/hive/lib/sm3.jar';
第四步:查看创建的函数
show functions;
注意:这里面会显示创建的函数,第三步不指定函数创建在哪个库下面的话,这里会默认创建到default下面
第五步:测试函数是否好用

创建函数过程中的问题,一直报错

报错类找不到异常,解决方案:
1.下载对应版本的jar包
https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on/1.64
2、放入$JAVA_HOME\jre\lib\ext目录下
3、修改配置文件$JAVA_HOME\jre\lib\security\java.security
加入一行配置:security.provider.按顺序填数字=org.bouncycastle.jce.provider.BouncyCastleProvider
注意:2和3的步骤,是需要把相应的jar包和文件拷贝到每一台机器上
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
