加密引擎

DM系统中内置了常用的DES,AES,RC4等类型的加密算法供用户使用,以此来保护数据的安全性。然而在有些特殊的环境下,这些加密算法可能不能满足用户的需求,用户可能希望使用自己特殊的加密算法,或强度更高的加密算法。DM的加密引擎功能则可以满足这样的需求。

用户只需要按照DM提供的加密引擎C语言编程接口,封装自己的加密算法,并编译成第三方加密动态库,即可以在DM的存储加密中使用自己的加密算法。

第三方加密动态库需要提供如下的对外接口,如下表所示。

表8.1 第三方加密接口定义
接口名称 功能说明
cipher_get_count 获取实现的算法个数
cipher_get_info 获取算法的基本信息,当实现了cipher_get_info_ex时,cipher_get_info自动失效
cipher_get_info_ex 获取算法的基本信息
cipher_encrypt_init 加密初始化
cipher_get_cipher_text_size 计算给定长度的明文,加密后得到的密文所占的字节数。
cipher_encrypt 加密函数
cipher_cleanup 回收密码算法在处理过程中申请的系统资源
cipher_decrypt_init 解密初始化
cipher_decrypt 解密函数
cipher_hash_init 散列过程的初始化工作
cipher_hash_update 计算消息msg的散列值
cipher_hash_final 散列值的实际长度
crypto_login 登录设备
crypto_logout 退出设备
crypto_read_cert 读取用户证书
cipher_gen_random 产生随机数
cipher_asym_sign 用户私钥对数据进行签名
cipher_asym_verify 用户公钥对数据进行验签
crypto_get_name 获取加密引擎名字
crypto_get_type 获取加密引擎类型。0:第三方软加密;1:第三方硬件加密;2:ukey。
crypto_encrypt 加密
crypto_decrypt 解密。与crypto_encrypt对应

8.1 编程接口介绍

8.1.1 算法信息相关接口

  1. cipher_get_count
ulint
cipher_get_count(
);

功能说明:

获取实现的算法个数。

返回值:

返回实现的算法个数。

  1. cipher_get_info
dm_bool
cipher_get_info(
    ulint seqno,
    ulint* cipher_id,
    byte** cipher_name,
    byte* type,
    ulint* blk_size,
    ulint* kh_size
);

参数说明:

seqno 算法的序号,从1开始,小于等于算法的个数

cipher_id 算法的内部ID,内部ID必须大于等于5000

cipher_name 算法名

type 算法类型

blk_size 块大小

kh_size key或者hash大小

功能说明:

获取算法的基本信息,有cipher_get_info_ex存在时,cipher_get_info失效

返回值

TRUE/FALSE 获取成功/获取失败

3. cipher_get_info_ex

dm_bool
cipher_get_info_ex(
	ulint  seqno,
	ulint* cipher_id,
	byte** cipher_name,
	byte*  type,
	ulint* blk_size,
	ulint* kh_size,
	byte*  work_mode 
);

参数说明

seqno 算法的序号,从1开始,小于等于算法的个数

cipher_id 算法的内部ID,内部ID必须大于等于5000

cipher_name 算法名

type 算法类型

blk_size 块大小

kh_size key或者hash大小

work_mode 工作模式。work_mode取值见下表

表8.2 work_mode取值
模式名取值 释义
0或WORK_MODE_ECB ECB(Electronic CodeBook),电子密码本模式
2或WORK_MODE_CBC CBC(Cipher-Block Chaining),密码块连接模式
4或WORK_MODE_CFB CFB(Cipher FeedBack),密文反馈模式
8或WORK_MODE_OFB OFB(Output FeedBack),输出反馈模式
16或WORK_MODE_CBC_NOPAD NOPAD(NO PADDING),非填充模式
32或WORK_MODE_ECB_NOPAD NOPAD(NO PADDING),非填充模式
64或WORK_MODE_EXTKEY WORK_MODE_EXTKEY(EXTERNAL KEY),外部密钥模式,专用算法模式
67或 WORK_MODE_KID WORK_MODE_KID(KEY ID),密钥ID模式, 专用算法模式。备份还原不支持使用WORK_MODE_KID的加密算法,该种加密算法也不支持作为external_cipher_name来进行数据库初始化

WORK_MODE_KID配置文件为dmkid.ini。dmkid.ini是使用WORK_MODE_KID加密算法的必要文件,文件位于DM安装目录$DM_HOME/bin目录下。dmkid.ini详细参数如下表所示:

表8.3 dmkid.ini中控制文件相关参数
参数名 缺省值 说明
InstanceURL http://127.0.0.1:8214/kmip 加密服务器URL
InstanceFormat 1 格式:none = 1, json = 1, xml = 2
InstanceUser kmipAdmin 用户名
InstancePwd 88888888 密码
InstanceCa ca证书 如果使用https, 则在这里指定ca证书
RETRY_TIMES 5 出现错误时,重试次数
RETRY_SLEEP 1000 每次重试等待时间(ms)
ENC_DEBUG 0 是否生成日志
ENC_LOG enc.log 日志文件完整路径
CONFIG_LOG_FILE 加密服务器生成日志完整路径

功能说明

获取算法的基本信息,有cipher_get_info_ex存在时,cipher_get_info失效

返回值

TRUE/FALSE 获取成功/获取失败

8.1.2 加密过程相关接口

  1. cipher_encrypt_init
dm_bool
cipher_encrypt_init(
    ulint inner_id,
    byte* key,
    ulint key_size,
    void** encrypt_para
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

key 输入参数,加密密钥

key_size 输入参数,密钥的字节数

encrypt_para 输入参数,加密过程的全局参数,由用户负责内存分配。该参数为加密过程全程使用的参数,由用户负责分配空间,其中可以携带key、 key_size、用户自定义信息等。该参数需要在整个加密过程中保持有效,后续加密相关接口中的encrypt_para都是由该接口生成

功能说明:

加密初始化

返回值

TRUE/FALSE 初始化成功/初始化失败

  1. cipher_get_cipher_text_size
lint
cipher_get_cipher_text_size(
    ulint inner_id,
    void* encrypt_para,
    lint plain_text_size
);

参数说明:

inner_id 输入参数,密码算法在加密引擎中的内部编号

encrypt_para 输入参数,cipher_encrypt_init的输出参数。ncrypt_para是cipher_encrypt_init时产生的输出参数,如何利用其中信息由用户决定

plain_text_size 输入参数,待加密的明文所占的字节数

功能说明

计算给定长度的明文加密后得到的密文所占的字节数。DM照返回值分配密文缓冲区。

返回值

与明文对应的密文所占的字节数。

  1. cipher_encrypt
lint
cipher_encrypt(
    ulint inner_id,
    void* encrypt_para,
    byte* plain_text,
    ulint plain_text_size,
    byte* cipher_text,
    ulint cipher_text_buf_size
);

参数说明:

inner_id 输入参数,密码算法在加密引擎中的内部编号

encrypt_para 输入参数,密码算法的全局变量。encrypt_para是cipher_encrypt_init时产生的输出参数,如何利用其中信息由用户决定

plain_text 输入参数,明文

plain_text_size 输入参数,明文所占的字节数

cipher_text 输出参数,密文

cipher_text_buf_size 输入参数,密文缓冲区的字节数

功能说明

加密。用户需要保证根据提供的参数不会出现写越界等问题,密文长度不能超过所提供的空间,这里的密文缓冲区字节数不会小于cipher_get_cipher_text_size的返回值, 用户还需确保cipher_get_cipher_text_size与该接口使用相同参数时,应该返回相同值。

返回值

加密后密文的长度。

  1. cipher_cleanup
void
cipher_cleanup(
    ulint inner_id,
    void* encrypt_para
);

参数说明:

inner_id 输入参数,密码算法在加密引擎中的内部编号

encrypt_para 输入参数,密码算法的全局参数

功能说明

回收密码算法在处理过程中申请的系统资源。一般情况下,用户需要在这里释放在cipher_encrypt_init或cipher_decrypt_init中创建的encrypt_para/decrypt_para。

返回值

无,假定该算法总是成功。

建议

在使用一个密码算法进行加密之前应首先对该密码算法进行初始化处理,DM数据库管理系统根据所指定的密码算法准备明文,并为密文分配密文缓冲区。然后调用加密函数进行加密,完成加密动作后回收加密过程中申请的系统资源。

8.1.3 解密过程相关接口

  1. cipher_decrypt_init
dm_bool
cipher_decrypt_init(
    ulint inner_id,
    byte* key,
    ulint key_size,
    void** decrypt_para
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

key 输入参数,加密密钥

key_size 输入参数,密钥的字节数

decrypt_para 输入参数,解密过程的全局参数,由用户分配内存

功能说明

解密初始化。用法与加密的cipher_encrypt_init类似。

返回值

TRUE/FALSE 初始化成功/初始化失败

  1. cipher_decrypt
lint
cipher_decrypt(
    ulint inner_id,
    void* decrypt_para,
    byte* cipher_text,
    ulint cipher_text_size,
    byte* plain_text,
    ulint plain_text_buf_size
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

decrypt_para 输入参数,cipher_decrypt_init的输出参数。该参数来自于cipher_decrypt_init的输出参数,如何利用其中数据由用户决定

cipher_text 输入参数,密文

cipher_text_size 输入参数,密文所占的字节数

plain_text 输出参数,明文

plain_text_buf_size 输入参数,明文缓冲区的长度

功能说明

解密。用户需要保证根据提供的参数不会出现写越界等问题,明文长度不能超过所提供的空间。

返回值

明文的实际长度。

建议

在使用一个密码算法进行解密之前应首先对该密码算法进行初始化处理,然后调用解密函数进行解密,完成解密动作后回收解密过程中申请的系统资源。

8.1.4 散列过程相关接口

  1. cipher_hash_init
dm_bool
cipher_hash_init(
    ulint inner_id,
    void** hash_para
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

hash_para 输入参数,散列过程的全局变量,由用户分配内存

功能说明

散列过程初始化。

返回值

TRUE/FALSE 初始化成功/初始化失败

  1. cipher_hash_update
void
cipher_hash_update(
    ulint inner_id,
    void* hash_para,
    byte* msg,
    ulint msg_size
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

hash_para 输入参数,散列过程中的全局参数

msg 待散列的消息

msg_size 消息长度

功能说明

计算消息的散列值。

返回值

  1. cipher_hash_final
lint
cipher_hash_final(
    ulint inner_id,
    void* hash_para,
    byte* digest,
    ulint digest_buf_size
);

参数说明:

inner_id 输入参数,调用的密码算法在加密引擎中的内部编号

hash_para 输入参数,散列过程中的全局参数

digest 输入参数,散列值

digest_buf_size 输入参数,散列缓冲区的大小

功能说明

将整个散列过程得到的散列值存放到digest中。

返回值

散列值的实际长度。

8.1.5 其他可选相关接口

  1. cipher_asym_sign
dm_bool
cipher_asym_sign(
    ulint inner_id,
    byte* prikey,
    ulint prikey_size,
    byte* data,
    ulint data_size,
    byte* signdata,
    ulint* signdata_buf_size
);

参数说明:

inner_id 调用的密码算法在加密引擎中的内部编号

prikey 私钥

prikey_size 私钥长度

data 需要进行签名的数据

data_size 数据的长度

signdata 数据的签名值

signdata_buf_size 签名值长度

功能说明

用户私钥对数据进行签名。

返回值

TRUE/FALSE 签名成功/签名失败

  1. cipher_asym_verify
dm_bool
cipher_asym_verify(
    ulint inner_id,
    byte* pubkey,
    ulint pubkey_size,
    byte* data,
    ulint data_size,
    byte* signdata,
    ulint signdata_size
);

参数说明:

inner_id 调用的密码算法在加密引擎中的内部编号

pubkey 公钥

pubkey_size 公钥长度

data 需要进行签名的数据

data_size 数据的长度

signdata 数据的签名值

signdata_buf_size 签名值长度

功能说明

用户公钥对数据进行验签。

返回值

TRUE/FALSE 验签成功/验签失败

  1. crypto_login
dm_bool
crypto_login(
    void** cipher_para,
    byte* pin,
    ulint pin_len
);

参数说明:

cipher_para 登录过程的全局参数,由用户负责内存分配

pin 设备口令

pin_len 口令长度

功能说明

登录设备。

返回值

TRUE/FALSE 登录成功/登录失败

  1. crypto_logout
dm_bool
crypto_logout(
	void* cipher_para
);

参数说明:

cipher_para 登录过程时使用的全局参数,此时需要释放

功能说明

退出设备。

返回值

TRUE/FALSE 退出成功/退出失败

  1. crypto_read_cert
dm_bool
crypto_read_cert(
    void* cipher_para,
    byte* cert,
    ulint* cert_len
);

参数说明:

cipher_para 登录过程时使用的全局参数

cert 输出参数,用户证书信息

cert_len 输出参数,用户证书长度

功能说明

读取用户证书。

返回值

TRUE/FALSE 读取成功/读取失败

  1. cipher_gen_random
dm_bool
cipher_gen_random(
    byte* random,
    ulint random_length
);

参数说明:

random 输出参数,生成的随机数

random_length 输入参数,需要产生随机数的长度

功能说明

产生随机数。

返回值

TRUE/FALSE 随机数生成成功/随机数生成失败

  1. cipher_get_name
dm_bool
crypto_get_name(
    byte** crypto_name,
    ulint* len
);

参数说明:

crypto_name 输出参数,加密引擎的名字

len 输出参数,加密引擎的名字的长度

功能说明

获取加密引擎名字。

返回值

TRUE/FALSE 获取成功/获取失败

  1. cipher_get_type
dm_bool
    crypto_get_type(
    ulint* crypto_type
);

参数说明:

crypto_type 输出参数,加密引擎的类型

功能说明

获取加密引擎类型。

返回值

TRUE/FALSE 获取成功/获取失败

  1. crypto_encrypt
lint
crypto_encrypt(
    byte* plain_text,
    ulint plain_text_size,
    byte* cipher_text,
    ulint cipher_text_buf_size
);

参数说明:

plain_text 输入参数,明文

plain_text_size 输入参数,明文所占的字节数

cipher_text 输出参数,密文

cipher_text_buf_size 输入参数,密文缓冲区的字节数

功能说明

加密。由第三方动态加密库指定加密的算法和密钥key,可以使用第三方设备(硬件加密卡、ukey)中的密钥key。为了安全起见,设备中的密钥key可以不加载到内存中,加密的全程都在第三方设备内完成。

返回值

加密后密文的长度

  1. crypto_decrypt
lint
crypto_decrypt(
    byte* cipher_text,
    ulint cipher_text_size,
    byte* plain_text,
    ulint plain_text_buf_size
);

参数说明:

cipher_text 输入参数,密文

cipher_text_buf_size 输入参数,密文所区的字节数

plain_text 输出参数,明文

plain_text_size 输入参数,明文缓冲区的字节数

功能说明

解密。与crypto_encrypt对应。

返回值

明文的实际长度

  1. cipher_get_key_id
lint 

cipher_get_key_id(

ulint   cipher_id, 

byte*  key_id,   

ulint   key_id_size,   

ulint*  key_size  

);

参数说明

cipher_id 输入参数,密文

key_id 输出参数,key_id

key_id_size 输入参数,key_id空间大小

key_size 输出参数,key_id实际大小

功能说明

生成加密key的标识符key_id,需要对应加密算法工作模式为WORK_MODE_KID。

返回值

是否生成成功

  1. cipher_free_key_id
lint 

cipher_free_key_id(

ulint   cipher_id, 

byte*  key_id,   

ulint   key_id_size 

);

参数说明

cipher_id 输入参数,密文

key_id 输入参数,key_id

key_id_size 输入参数,key_id空间大小

功能说明

释放加密key的标识符key_id,需要对应加密算法工作模式为WORK_MODE_KID。

返回值

是否释放成功

8.2 接口库文件使用说明

想要使用自己的加密算法的用户需要用C语言编写实现8.1节中介绍的接口(8.1.5节中的接口可选),并编译生成第三方动态库文件,如:external_crypto.dll(LINUX操作系统下为libexternal_crypto.so)。

DM支持同时加载多个第三方动态库文件。但这些DLL库文件必须放在DM数据库服务器所在BIN目录的external_crypto_libs子目录下。external_crypto_libs目录需用户自己创建。如果是DM控制台工具,需将这些DLL库文件放在CONSOLE工具所在TOOL目录的external_crypto_libs子目录下。

为了保证加密算法有效性,所有第三方库文件中的加密方法名及ID不同。DM提供一个动态视图V$EXTERNAL_CIPHERS,用户可查看所有的第三方加密算法的ID、名称、所在的库文件以及是否有效标记。

V$EXTERNAL_CIPHERS的结构如下表所示。

表8.4 V$EXTERNAL_CIPHERS结构
序号 数据类型 说明
1 ID INTEGER 算法ID
2 NAME VARCHAR(128) 算法名
3 LIB VARCHAR(300) 算法所在的lib库文件名
4 VALID CHAR 算法是否有效。‘Y’:是;‘N’:否

8.3 ukey使用说明

DM支持使用UKEY进行身份鉴别和加密。使用UKEY进行身份鉴别时,应按照8.1节的介绍编写两个动态库,分别作用于客户端和服务器。编写动态库时应注意:

  1. 客户端和服务器端的动态库crypto_get_name()的返回值必须相同;
  2. 客户端动态库的名字*.dll/*.so中的*必须与crypto_get_name()返回值相同,否则JDBC驱动无法完成UKEY鉴别,DPI接口无此要求;
  3. 客户端动态库的crypto_get_type()应返回2,表示移动设备UKEY;服务器端动态库的crypto_get_type()返回1,表示软件或硬件加密卡。

8.4 DM提供的第三方加密算法

DM 提供了一些第三方加密算法供用户使用,例如:SM3、SM4算法。第三方加密算法的动态库文件为位于bin/external_crypto_libs文件夹下的openssl1.1.1_crypto.dll(Windows操作系统)或libopenssl_crypto.so(Linux操作系统)。

表8.5 DM提供的第三方加密算法(SM3、SM4)
算法名称 算法类型 分组长度 密钥长度
OPENSSL_SM4_ECB 分组加密算法 16 16
OPENSSL_SM4_CBC 分组加密算法 16 16
OPENSSL_SM4_CFB 分组加密算法 16 16
OPENSSL_SM4_OFB 分组加密算法 16 16
OPENSSL_SM3 散列算法 - -
OPENSSL_SM4_ECB_NOPAD 分组加密算法 16 16
OPENSSL_SM4_CBC_NOPAD 分组加密算法 16 16
OPENSSL_SM4_CFB_V1 分组加密算法 16 16
OPENSSL_SM4_OFB_V1 分组加密算法 16 16

SM3、SM4算法可以通过查询动态视图V​CIPHERS查看。因为通过external_crypto_libs文件夹下的文件进行支持,因此也可以通过查询动态视图Vexternal_ciphers进行查询。

select * from V$external_ciphers ;

    行号           ID                               NAME                                                        LIB                         VALID
---------- ----------- --------------------------------- ------------------------------- ----------
    1               5201            OPENSSL_SM4_ECB                         openssl1.1.1_crypto.dll                Y
    2               5202            OPENSSL_SM4_CBC                        openssl1.1.1_crypto.dll                Y
    3               5203            OPENSSL_SM4_CFB                        openssl1.1.1_crypto.dll                Y
    4               5204            OPENSSL_SM4_OFB                        openssl1.1.1_crypto.dll                Y
    5               5207            OPENSSL_SM3                                 openssl1.1.1_crypto.dll                 Y
    6               5205            OPENSSL_SM4_ECB_NOPAD         openssl1.1.1_crypto.dll                Y
    7               5206            OPENSSL_SM4_CBC_NOPAD         openssl1.1.1_crypto.dll                Y
    8               5208            OPENSSL_SM4_CFB_V1                   openssl1.1.1_crypto.dll               Y
    9               5209            OPENSSL_SM4_OFB_V1                   openssl1.1.1_crypto.dll               Y

DM提供的SM3,SM4算法是由openssl提供,DM进行封装的。因此,如果有用户不使用DM提供的openssl第三方库,则用户需要保证使用版本号大于1.1.1 的openssl,大于1.1.1的版本才包含SM3,SM4算法。

其中,OPENSSL_SM4_CFB_V1、OPENSSL_SM4_OFB_V1算法分别是OPENSSL_SM4_CFB、OPENSSL_SM4_OFB算法的新版本,不与老版本兼容,因此当用户需要使用上述算法时,建议优先选择新版本。

8.5 编程实例

本节用一个实例来说明DM加密引擎接口的编程方法。

例子中用户自定义加密算法为实现一个简单的异或加密算法和一个HASH算法。异或加密算法包括单字节的流加密(xor1、xor2)和4字节的块加密方式(xor3),HASH算法为MD5(名称为new_md5)。

第一步,生成动态库。

使用Microsoft Visual Studio 2008创建新项目mycrypto,将xor.h和xor.c、hash.h和hash.c、crypto_engine.h和my_crypto.c生成动态库mycrypto.dll。其中crypto_engine.h被放在DM安装目录的include文件夹中。

涉及到的文件如下:

  • xor.h

说明:异或加密算法函数的声明。

//xoh.h :declare the xor cipher
##ifndef CRYPTO_ENGINE_H
typedef unsigned char byte;
##endif
int
xor_encrypt(
    byte key,
    byte* plain_text,
    int plain_text_len,
    byte* cipher_text,
    int cipher_text_len);
int
xor_decrypt(
    byte key,
    byte* cipher_text,
    int cipher_text_len,
    byte* plain_text,
    int plain_text_len);
int
xor_data_block_encrypt(
    int key,
    byte* in_text,
    int in_text_len,
    byte* out_text,
    int out_text_len);
int
xor_data_block_decrypt(
    int key,
    byte* in_text,
    int in_text_len,
    byte* out_text,
    int out_text_len);

  • xor.c

说明:异或加密算法的实现。

// xor.c : implement the xor cipher.
##include <stdio.h>
##include <stdlib.h>
##include "xor.h"
int
xor_data(
    byte key,
    byte* in_text,
    int in_text_len,
    byte* out_text,
    int out_text_len)
{
    int i = 0;
    for (i = 0; i < in_text_len; i++)
    {
    	out_text[i] = in_text[i] ^ key;
    }
    return in_text_len;
}
int
xor_data_block_encrypt(
        int key,
        byte* in_text,
        int in_text_len,
        byte* out_text,
        int out_text_len)
{
    int i = 0;
    int in_buf = 0;
    int out_buf = 0;
    int out_len = 0;
    int pos = 0;
    int block_len = sizeof(int);
    byte* p = NULL;
    byte* t = NULL;
    int n = 0;
    int m = 0;
    int fill_num = 0;
    n = in_text_len / block_len + 1;
    m = in_text_len % block_len;
    out_len = block_len * n;
    p = (byte*)malloc(out_len);
    memset(p, 0, out_len);
    memcpy(p, in_text, in_text_len);
    fill_num = out_len - in_text_len;
    memset(p + in_text_len, fill_num, out_len - in_text_len);
    for (i = 0; i < out_len; i++)
    {
        p[i] = p[i] ^ key;
    }
    memcpy(out_text, p, out_len);
    free(p);
    return out_len;
}
int
xor_data_block_decrypt(
    int key,
    byte* in_text,
    int in_text_len,
    byte* out_text,
    int out_text_len)
{
    int i = 0;
    int in_buf = 0;
    int out_buf = 0;
    int out_len = 0;
    int pos = 0;
    int block_len = sizeof(int);
    byte* p = NULL;
    byte* t = NULL;
    int n = 0;
    int m = 0;
    int fill_num = 0;
    n = in_text_len / block_len;
    m = in_text_len % block_len;
    if (m != 0)
    {
    	return -1;
    }
    p = (byte*)malloc(in_text_len);
    memcpy(p, in_text, in_text_len);
    for (i = 0; i < in_text_len; i++)
    {
    	p[i] = p[i] ^ key;
    }
    fill_num = p[in_text_len - 1];
    memcpy(out_text, p, in_text_len - fill_num);
    free(p);
    return in_text_len - fill_num;
}
int
xor_encrypt(
    byte key,
    byte* plain_text,
    int plain_text_len,
    byte* cipher_text,
    int cipher_text_len)
{
return xor_data(key, plain_text, plain_text_len, cipher_text, cipher_text_len);
}
int
xor_decrypt(
    byte key,
    byte* cipher_text,
    int cipher_text_len,
    byte* plain_text,
    int plain_text_len)
{
return xor_data(key, cipher_text, cipher_text_len, plain_text, plain_text_len);
}
  • hash.h

说明:hash算法函数的声明。

// hash.h
typedef struct {
    unsigned int state[4];
    unsigned int count[2];
    unsigned char buffer[64];
} MD5Context;
void MD5_Init(MD5Context * context);
void MD5_Update(MD5Context * context, unsigned char * buf, int len);
void MD5_Final(MD5Context * context, unsigned char digest[16]);
  • hash.c

说明:hash算法实现。

##include <string.h>
##include "hash.h"
##define S11 7
##define S12 12
##define S13 17
##define S14 22
##define S21 5
##define S22 9
##define S23 14
##define S24 20
##define S31 4
##define S32 11
##define S33 16
##define S34 23
##define S41 6
##define S42 10
##define S43 15
##define S44 21
static unsigned char PADDING[64] =
{0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
##define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
##define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
##define H(x, y, z) ((x) ^ (y) ^ (z))
##define I(x, y, z) ((y) ^ ((x) | (~z)))
##define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
##define FF(a, b, c, d, x, s, ac) \
    { \
    (a) += F((b), (c), (d)) + (x) + (unsigned int)(ac); \
    (a) = ROTATE_LEFT((a), (s)); \
    (a) += (b); \
    }
##define GG(a, b, c, d, x, s, ac) \
    { \
    (a) += G((b), (c), (d)) + (x) + (unsigned int)(ac); \
    (a) = ROTATE_LEFT((a), (s)); \
    (a) += (b); \
    }
##define HH(a, b, c, d, x, s, ac) \
    { \
    (a) += H((b), (c), (d)) + (x) + (unsigned int)(ac); \
    (a) = ROTATE_LEFT((a), (s)); \
    (a) += (b); \
    }
##define II(a, b, c, d, x, s, ac) \
    { \
    (a) += I((b), (c), (d)) + (x) + (unsigned int)(ac); \
    (a) = ROTATE_LEFT((a), (s)); \
    (a) += (b); \
    }
static void MD5_Encode(unsigned char * output, unsigned int * input, int len)
    {
        unsigned int i, j;
        for (i = 0, j = 0; j < (unsigned int)len; i++, j += 4)
        {
            output[j] = (unsigned char) (input[i] & 0xff);
            output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
            output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
            output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
        }
    }
static void MD5_Decode(unsigned int * output, unsigned char * input, int len)
    {
    unsigned int i, j;
    for (i = 0, j = 0; j < (unsigned int)len; i++, j += 4)
        {
            output[i] = ((unsigned int) input[j]) |
            (((unsigned int) input[j + 1]) << 8) |
            (((unsigned int) input[j + 2]) << 16) |
            (((unsigned int) input[j + 3]) << 24);
        }
    }
static void MD5_Transform(unsigned int state[4], unsigned char block[64])
{
    unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    MD5_Decode(x, block, 64);
    /* Round 1 */
    FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
    FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
    FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
    FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
    FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
    FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
    FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
    FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
    FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
    FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
    FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
    /* Round 2 */
    GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
    GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
    GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
    GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
    GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
    GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
    GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
    GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
    GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
    GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
    GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
    /* Round 3 */
    HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
    HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
    HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
    HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
    HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
    HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
    HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
    HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
    HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
    HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
    /* Round 4 */
    II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
    II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
    II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
    II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
    II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
    II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
    II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
    II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
    II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
    II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
    state[0] += a;
    state[1] += b;
    state[2] += c;
    state[3] += d;
    memset((char *) x, 0, sizeof(x));
}
void MD5_Init(MD5Context * context)
{
    context->count[0] = context->count[1] = 0;
    context->state[0] = 0x67452301;
    context->state[1] = 0xefcdab89;
    context->state[2] = 0x98badcfe;
    context->state[3] = 0x10325476;
}
void MD5_Update(MD5Context * context, unsigned char * buf, int len)
{
    unsigned int i, index, partLen;
    index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
    if ((context->count[0] += ((unsigned int) len << 3)) < ((unsigned int) len << 3))
    context->count[1]++;
    context->count[1] += ((unsigned int) len >> 29);
    partLen = 64 - index;
    if ((unsigned int)len >= partLen)
    {
        memcpy((char *) &context->buffer[index], (char *) buf, partLen);
        MD5_Transform(context->state, context->buffer);
        for (i = partLen; i + 63 < (unsigned int)len; i += 64)
        MD5_Transform(context->state, &buf[i]);
        index = 0;
    }
    else
    {
        i = 0;
    }
    memcpy((char *) &context->buffer[index], (char *) &buf[i], len - i);
}
void MD5_Final(MD5Context * context, unsigned char digest[16])
{
    unsigned char bits[8];
    unsigned int index, padLen;
    MD5_Encode(bits, context->count, 8);
    index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
    padLen = (index < 56) ? (56 - index) : (120 - index);
    MD5_Update(context, PADDING, padLen);
    MD5_Update(context, bits, 8);
    MD5_Encode(digest, context->state, 16);
    memset((char *) context, 0, sizeof(*context));
}
  • my_crypto.c

说明:封装供DM加载的函数接口。

//my_crypto.c
##include <stdlib.h>
##include "crypto_engine.h"
##include "xor.h"
##include "hash.h"
##define MIN_EXTERNAL_CIPHER_ID 5000
##define CYT_TYPE_UNKNOWN 0 //类型, 未知算法
##defineCYT_TYPE_SYM_BLOCK_ENCRYPT 1 //类型, 分组对称加密算法
##define CYT_TYPE_SYM_STREAM_ENCRYPT 2 //类型, 流式对称加密算法
##define CYT_TYPE_ASYM_ENCRYPT 3 //类型, 非对称加密算法, 保留
##define CYT_TYPE_HASH 4 //类型, 散列算法
##define KEY1 ((byte)(0XAA))
##define KEY2 ((byte)(0x55))
##define KEY3 ((int)(0xCCCCCCCC))
DllExport
ulint
cipher_get_count(
)
{
	return 4;
}
DllExport
dm_bool
cipher_get_info(
    ulint seqno,
    ulint* cipher_id,
    byte** cipher_name,
    byte* type,
    ulint* blk_size,
    ulint* kh_size
)
{
    switch (seqno)
    {
    case 1:
        *cipher_id = MIN_EXTERNAL_CIPHER_ID;
        *cipher_name = "xor1";
        *type = CYT_TYPE_SYM_STREAM_ENCRYPT;
        *blk_size = 0;
        *kh_size = sizeof(KEY1);
        break;
    case 2:
        *cipher_id = MIN_EXTERNAL_CIPHER_ID + 1;
        *cipher_name = "xor2";
        *type = CYT_TYPE_SYM_STREAM_ENCRYPT;
        *blk_size = 0;
        *kh_size = sizeof(KEY1);
        break;
    case 3:
        *cipher_id = MIN_EXTERNAL_CIPHER_ID + 2;
        *cipher_name = "xor3";
        *type = CYT_TYPE_SYM_BLOCK_ENCRYPT;
        *blk_size = 4;
        *kh_size = sizeof(KEY1);
        break;
    case 4:
        *cipher_id = MIN_EXTERNAL_CIPHER_ID + 3;
        *cipher_name = "new_md5";
        *type = CYT_TYPE_HASH;
        *blk_size = 0;
        *kh_size = 16;
        break;
    default:
        return DM_FALSE;
    }
    return DM_TRUE;
}

DllExport
dm_bool
cipher_get_para(
	ulint 	cipher_id,
	ulint	para_id,
 	void* 	value
){ 
switch (cipher_id)
   {
    case IN_EXTERNAL_CIPHER_ID:
        switch (para_id)
    	   {
    		case CYT_PARA_WORKMODE:
         		*(byte*)value = 0;
         		break;
   			case CYT_PARA_EXTENDSIZE:
        		*(int*)value = 0;
        		break;
			default:
				return DM_FALSE;
    	   }
        break;
    case IN_EXTERNAL_CIPHER_ID+1:
        switch (para_id)
    	   {
    		case CYT_PARA_WORKMODE:
         		*(byte*)value = 0;
         		break;
   			case CYT_PARA_EXTENDSIZE:
        		*(int*)value = 0;
        		break;
			default:
				return DM_FALSE;
    	   }
        break;
    case IN_EXTERNAL_CIPHER_ID+2:
        switch (para_id)
    	   {
    		case CYT_PARA_WORKMODE:
         		*(byte*)value = 0;
         		break;
   			case CYT_PARA_EXTENDSIZE:
        		*(int*)value = 4;
        		break;
			default:
				return DM_FALSE;
    	   }
        break;
    case IN_EXTERNAL_CIPHER_ID+3:
        switch (para_id)
    	   {
    		case CYT_PARA_WORKMODE:
         		*(byte*)value = 0;
         		break;
  			 case CYT_PARA_EXTENDSIZE:
        		*(int*)value = 0;
        		break;
			default:
				return DM_FALSE;
    	   }
        break;
    default:
        return DM_FALSE; 
	}
    return DM_TRUE;
}

DllExport
dm_bool
cipher_encrypt_init(
    ulint inner_id,
    byte* key,
    ulint key_size,
    void** encrypt_para
)
{
    switch (inner_id)
    {
        case MIN_EXTERNAL_CIPHER_ID:
            break;
        case MIN_EXTERNAL_CIPHER_ID + 1:
            break;
        case MIN_EXTERNAL_CIPHER_ID + 2:
            break;
        default:
            return DM_FALSE;
      }
     return DM_TRUE;
}
DllExport
lint
cipher_get_cipher_text_size(
    ulint inner_id,
    void* cipher_para,
    lint plain_text_size
)
{
    lint len = 0;
    lint block_len = sizeof(int);
    switch (inner_id)
    {
        case MIN_EXTERNAL_CIPHER_ID:
            len = plain_text_size;
            break;
        case MIN_EXTERNAL_CIPHER_ID + 1:
            len = plain_text_size;
            break;
        case MIN_EXTERNAL_CIPHER_ID + 2:
            len = plain_text_size + block_len;
            break;
        default:
        	return -1;
    }
    return len;
}
DllExport
lint
cipher_encrypt(
    ulint inner_id,
    void* cipher_para,
    byte* plain_text,
    ulint plain_text_size,
    byte* cipher_text,
    ulint cipher_text_buf_size
)
{
    int len = plain_text_size;
    if (plain_text_size > cipher_text_buf_size)
    {
    	return -1;
    }
    switch(inner_id)
        {
        case MIN_EXTERNAL_CIPHER_ID:
            len = xor_encrypt(KEY1, plain_text, plain_text_size, cipher_text,cipher_text_buf_size);
            break;
        case MIN_EXTERNAL_CIPHER_ID + 1:
            len = xor_encrypt(KEY2, plain_text, plain_text_size, cipher_text, cipher_text_buf_size);
            break;
        case MIN_EXTERNAL_CIPHER_ID + 2:
            len = xor_data_block_encrypt(KEY3, plain_text, plain_text_size, cipher_text, cipher_text_buf_size);
            break;
        default:
        	return -1;
        }
    return len;
}
DllExport
dm_bool
cipher_decrypt_init(
    ulint inner_id,
    byte* key,
    ulint key_size,
    void** decrypt_para
)
{
    switch (inner_id)
    {
        case MIN_EXTERNAL_CIPHER_ID:
        	break;
        case MIN_EXTERNAL_CIPHER_ID + 1:
        	break;
        case MIN_EXTERNAL_CIPHER_ID + 2:
        	break;
        default:
        	return DM_FALSE;
    }
	return DM_TRUE;
}
DllExport
lint
    cipher_decrypt(
    ulint inner_id,
    void* decrypt_para,
    byte* cipher_text,
    ulint cipher_text_size,
    byte* plain_text,
    ulint plain_text_buf_size
)
{
dm_bool bRet = DM_FALSE;
int len = cipher_text_size;
if (cipher_text_size > plain_text_buf_size)
{
	return -1;
}
switch(inner_id)
    {
        case MIN_EXTERNAL_CIPHER_ID:
            len = xor_decrypt(KEY1, cipher_text, cipher_text_size, plain_text, plain_text_buf_size);
            break;
        case MIN_EXTERNAL_CIPHER_ID + 1:
            len = xor_decrypt(KEY2, cipher_text, cipher_text_size, plain_text, plain_text_buf_size);
            break;
        case MIN_EXTERNAL_CIPHER_ID + 2:
            len = xor_data_block_decrypt(KEY3, cipher_text, cipher_text_size, plain_text, plain_text_buf_size);
            break;
        default:
            return -1;
    }
return len;
}
DllExport
dm_bool
cipher_hash_init(
    ulint inner_id,
    void** hash_para
)
{
MD5Context* md5_context = NULL;
switch (inner_id)
{
    case MIN_EXTERNAL_CIPHER_ID + 3:
        *hash_para = malloc(sizeof(MD5Context));
        md5_context = (MD5Context*)(*hash_para);
        MD5_Init(md5_context);
        break;
    default:
    	return DM_FALSE;
}
return DM_TRUE;
}
DllExport
void
cipher_hash_update(
    ulint inner_id,
    void* hash_para,
    byte* msg,
    ulint msg_size
)
{
MD5Context* md5_context = NULL;
switch (inner_id)
{
    case MIN_EXTERNAL_CIPHER_ID + 3:
        md5_context = (MD5Context*)(hash_para);
        MD5_Update(md5_context, msg, msg_size);
        break;
    default:
    	return;
}
return;
}
DllExport
lint
cipher_hash_final(
    ulint inner_id,
    void* hash_para,
    byte* digest,
    ulint digest_buf_size
)
{
lint len = 0;
MD5Context* md5_context = NULL;
switch (inner_id)
{
    case MIN_EXTERNAL_CIPHER_ID + 3:
        md5_context = (MD5Context*)(hash_para);
        MD5_Final(md5_context, digest);
        len = 16; // MD5后为一个bit的摘要
        free(md5_context);
        break;
    default:
    	return -1;
}
	return len;
}
DllExport
void
cipher_cleanup(
    ulint inner_id,
    void* cipher_para
)
{
switch (inner_id)
{
    case MIN_EXTERNAL_CIPHER_ID:
    	break;
    case MIN_EXTERNAL_CIPHER_ID + 1:
    	break;
    case MIN_EXTERNAL_CIPHER_ID + 2:
    	break;
    case MIN_EXTERNAL_CIPHER_ID + 3:
    	break;
    default:
    	return;
}
	return;
}
DllExport
dm_bool
cipher_asym_sign(
    ulint inner_id,
    byte* prikey, //私钥签名
    ulint prikey_size,
    byte* data,
    ulint data_size,
    byte* signdata,
    ulint* signdata_buf_size
)
{
	return DM_FALSE;
}
DllExport
dm_bool
cipher_asym_verify(
    ulint inner_id,
    byte* pubkey, //公钥验签
    ulint pubkey_size,
    byte* data,
    ulint data_size,
    byte* signdata,
    ulint signdata_size
)
{
	return DM_FALSE;
}
DllExport
dm_bool
crypto_login(
    void** cipher_para,
    byte* pin,
    ulint pin_len
)
{
	return DM_FALSE;
}
DllExport
dm_bool
crypto_logout(
	void* cipher_para
)
{
	return DM_FALSE;
}
DllExport
dm_bool
crypto_read_cert(
    void* cipher_para,
    byte* cert,
    ulint * cert_len
)
{
	return DM_FALSE;
}
DllExport
dm_bool
cipher_gen_random(
    byte* random,
    ulint random_length
)
{
	return DM_FALSE;
}
DllExport
dm_bool
crypto_get_name(
    byte** crypto_name,
    ulint* len
)
{
*crypto_name = "mycrypto";
*len = 8;
return DM_TRUE;
}
DllExport
dm_bool
crypto_get_type(
	ulint* crypto_type
)
{
    *crypto_type = 0;
    return DM_TRUE;
}
  • Crypto_engine.h

说明:库接口说明文件。

##ifndef CRYPTO_ENGINE_H
##define CRYPTO_ENGINE_H
##ifndef dm_h
typedef int   lint;
typedef short sint;
typedef signed char tint;
typedef unsigned int ulint;   
typedef unsigned short usint;
typedef unsigned char byte;
##ifdef _WIN64
##define dm_int3264 __int64
##define dm_uint3264 unsigned __int64
##else
##define dm_int3264 long
##define dm_uint3264 unsigned long
##endif
##endif //##ifndef dm_h
##ifdef WIN32
##define DllImport __declspec( dllimport )
##define DllExport __declspec( dllexport )
##else
##define DllImport 
##define DllExport 
##endif
##define  MIN_EXTERNAL_CIPHER_ID         5000
##define  CYT_TYPE_UNKNOWN		        0			//type, unknown arithmetic   
##define	 CYT_TYPE_SYM_BLOCK_ENCRYPT	    1			//type, symmetry encrypt arithmetic  
##define  CYT_TYPE_SYM_STREAM_ENCRYPT	2			//type, flow encrypt arithmetic  
##define  CYT_TYPE_ASYM_ENCRYPT		    3			//type, unsymmetrical encrypt arithmetic, reserved   
##define  CYT_TYPE_HASH				    4			//type, hash arithmetic
##ifdef __cplusplus
extern "C" {
##endif
##ifdef WIN32
##define dm_bool long
##else
##define dm_bool unsigned int
##endif
##define DM_FALSE	0
##define DM_TRUE	1
DllExport
ulint
cipher_get_count(
);
DllExport
dm_bool
cipher_get_info(
    ulint	seqno,
    ulint*	cipher_id,
    byte**	cipher_name,
    byte*	type,
    ulint*	blk_size,
    ulint*	kh_size 
);
DllExport
dm_bool
cipher_encrypt_init(
	ulint	inner_id,
	byte*	key,
	ulint	key_size,
	void**	encrypt_para
);
DllExport
lint
cipher_get_cipher_text_size(
	ulint	inner_id,
	void*	cipher_para,
	lint	plain_text_size
);
DllExport
lint
cipher_encrypt(
	ulint	inner_id,
	void*	encrypt_para,
	byte*	plain_text,
	ulint	plain_text_size,
	byte*	cipher_text,
	ulint	cipher_text_buf_size
);
DllExport
dm_bool
cipher_decrypt_init(
	ulint	inner_id,
	byte*	key,
	ulint	key_size,
	void**	decrypt_para
);
DllExport
lint
cipher_decrypt(
   ulint	inner_id,
   void*	decrypt_para,
   byte*	cipher_text,
   ulint	cipher_text_size,
   byte*	plain_text,
   ulint	plain_text_buf_size
);
DllExport
dm_bool
cipher_hash_init(
	ulint	inner_id,
	void**	hash_para
);
DllExport
void
cipher_hash_update(
	ulint	inner_id,
	void*	hash_para,
	byte*	msg,
	ulint	msg_size
);
DllExport
lint
cipher_hash_final(
	ulint	inner_id,
	void*	hash_para,
	byte*	digest,
	ulint	digest_buf_size
);
DllExport
void
cipher_cleanup(
	ulint	inner_id,
	void*	hash_para
);
##ifdef __cplusplus
}
##endif
##endif

第二步,在安装目录bin下创建一个external_crypto_libs文件夹。将第一步中生成的动态库mycrypto.dll放入该文件夹中。

第三步,重启服务器。

第四步,至此,可以使用自定义的算法了。也可以通过V$EXTERNAL_CIPHERS查看到。

SQL> select * from V$EXTERNAL_CIPHERS;

行号 			ID 		NAME 		LIB 	VALID
---------- ----------- ------- --------- -----
1 			5000 		xor1 	mycrypto.dll Y
2 			5001 		xor2 	mycrypto.dll Y
3 			5002 		xor3 	mycrypto.dll Y
4 			5003 		new_md5 mycrypto.dll Y
微信扫码
分享文档
扫一扫
联系客服