IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【openGauss】用plpgsql实现sha256算法(踩坑填坑实录) -> 正文阅读

[大数据]【openGauss】用plpgsql实现sha256算法(踩坑填坑实录)

前言

在开发中,经常会使用类似MD5/ SHA-1/ SHA-2这样的hash算法来对数据进行处理,以防原始信息泄露,比如密码的存储。
SHA-2中的SHA256,安全性比MD5更高,因此很多数据库增加了对SHA256计算的支持。
比如从oracle12c起,数据库内原生提供了DBMS_CRYPTO包和STANDARD_HASH函数,可以用来进行sha256计算。在postgresql中,可以通过安装pgcrypto扩展来支持,安装命令也很简单。

create extension pgcrypto;

但是,如果是基于postgresql的openGauss(2.1.0),事情就没这么简单了,需要搭建编译环境、下载源码、编译等一系列操作。
但好在,openGauss2.1.0支持了oracle风格的package对象,只要我们能找到有人为oracle写的plsql包,那么大概率是可以移植到openGauss里去的。
想到几年前我参与的某个项目,需要使用oracle11g数据库调用外部http接口,而这个接口需要使用sha256算法来计算签名,此版本的oracle是不支持sha256算法的,所以在网上找到了一个开源的plsql包
https://github.com/CruiserX/sha256_plsql

开始进行适配

二话不说,先直接往openGauss里干,注意数据库要为A兼容模式。(参考https://www.modb.pro/db/239429

结果当然是报错了。

首先,这个包使用了utl_raw这个包,这在openGauss里是不会自带的,不过我在compat-tools里增加了这个包,因此需要先安装compat-tools,或者单独安装utl_raw这个包
compat-tools下载
utl_raw下载

1. type table 不支持

TYPE ta_number IS TABLE OF NUMBER INDEX BY binary_integer;

这是定义一列number类型的表作为类型,既然报错,那么去掉ta_number的定义,把下面的引用了ta_number的全部改成number[]

2. PL/pgSQL functions cannot accept type record

    TYPE tr_ctx IS RECORD (
        H     TA_NUMBER, --//8
        total TA_NUMBER, --//2
        buflen NUMBER,
        buffer32 TA_NUMBER  --//32
    );

去掉包内的tr_ctx定义,创建个单独的type(注意重名冲突问题)

CREATE  TYPE tr_ctx AS  (
        H     NUMBER[], --//8
        total NUMBER[], --//2
        buflen NUMBER,
        buffer32 NUMBER[]  --//32
    );

3. 不支持参数的 NOCOPY属性

PROCEDURE sha256_init_ctx (ctx IN OUT NOCOPY TR_CTX);

直接把nocopy全部替换成空。
至此包头编译过去了,但编译包体提示

syntax error at end of input

而且不说是哪一行(在oracle中会提示错误的具体位置),只能逐段注释编译,最终发现了一个其实没有语法问题的位置

4. syntax error at end of input

add := CASE WHEN 128 - left_over > t_len THEN t_len ELSE 128 - left_over END;

这一段单独放在其他过程里面是不会有问题的,但是在这里报错了,原因不明,疑似bug。起初我以为是add关键词的原因,但改了后报相同的错。直接改成select into就好了

select CASE WHEN 128 - left_over > t_len THEN t_len ELSE 128 - left_over END into add;

然后包体也编译过去了。不过事情还没完,尝试调用这个包计算sha256,报错

5. ERROR: schema “ctx” does not exist

经翻阅相关文档,发现复合类型此处会存在一个歧义,文档中说是要用(ctx).col这种方式来避免歧义,但实测此方法此处不适用,因为这么改了后会提示 "("附近的语法有错误。然后我尝试把所有取数组指定位置元素的()改成了[],比如

ctx.buffer32(left_over_blk)

改成

ctx.buffer32[left_over_blk]

注意,要改动的地方多达五十多处,一个都不能漏
再尝试调用,就没报这个错了,但报了个新的错误

6. ERROR: invalid number format model

to_number(utl_raw.substr(t_buffer,idx,1),'0x')

这里是因为openGauss的to_number不支持 ‘0x’这个格式,其实这个和’xx’是一样的,因此把所有的’0x’直接替换成’xx’ .
接着调用,报新的错误

7. ERROR: function “sha256_finish_ctx” with 1 parameters doesn’t exist

 PROCEDURE sha256_finish_ctx (ctx IN OUT  TR_CTX,
                                   resbuf OUT  NUMBER[]);
sha256_finish_ctx(ctx, res);

这个目测和pg内核有关,这明明是个PROCEDURE,报错提示却是个function;而且调用这个过程时明明是传的两个参数,提示却说不存在1个参数的它,当我把resbuf这个参数也改成 in out,这个错就不报了,但又报了个新的错误

8. ERROR: array value must start with “{” or dimension information

我跟踪到,还是此处的问题

sha256_finish_ctx(ctx, res);

res这个参数,在此过程内部,最后得到了准确的值,但是一跳出这个过程,这个参数就变成了空。
此处应该也是pg内核的一个问题,对于过程中的数组类型参数,不会传出值,于是我把它改成了一个函数,用return返回res参数。

测试

至此,这个包终于可以调用成功了,检查输出结果

select sha256.ENCRYPT('aa') ;
--961b6dd3ede3cb8ecbaacbd68de040cd78eb2ed5889130cceb4c49268ea4d506

image-1651042932329
然后在oracle中查询
image-1651042965558
可以发现结果完全一致。

但是,我发现个很严重的问题,上述的这个sql,我在oracle中查询只需要0.277秒,但是在openGauss中查询则需要3秒。
猜测原因,一方面可能与我写的UTL_RAW包有关,毕竟不是用的原生c语言开发的;另一方面nocopy这个特性的确能提高性能;再者就是两个数据库运行的环境是存在差异的。

总结

虽然计算耗时比较严重,但是对一些速度要求不高的非频繁计算请求,有了总比没有好。上面列了8个点的问题,这也没有对这个包整体的逻辑进行大幅调整,即可"正常"使用,这也说明了openGauss对oracle语法强大的兼容性。
但是,如果对性能有强烈要求,建议还是安装相关扩展来使用。

最后附上我修改完的代码
https://gitee.com/darkathena/sha256-opengauss

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:12:55  更:2022-04-29 12:13:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:39:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码