加密引擎

DM 系统中内置了常用的 DES,AES,RC4,SHA 等类型的加密和散列算法供用户使用,以此来保护数据的安全性。然而在有些特殊的环境下,这些算法可能不能满足用户的需求,用户可能希望使用自己特殊的或更高强度的加密和散列算法(例如:国密算法)。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 获取成功/获取失败

  1. 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 获取成功/获取失败

4. cipher_get_para

dmbool cipher_get_para(
	ulint cipher_id,
	ulint  para_id,
	void* value
);

参数说明

cipher_id 算法的 ID,第三方加密算法的 ID 必须大于等于 5000

para_id 参数 ID,目前仅支持两个参数,0 表示 WORKMODE,1 表示 EXTENDSIZE

value 参数值。类型将根据 para_id 变化:para_id 为 0 时,value 为 unsigned char*;para_id 为 1 时,value 为 unsigned int*。用户须保证不会写越界。

功能说明

获取当前加密算法的当前参数的值,目前支持获取 WORK_MODE 和 EXTEND_SIZE。WORK_MODE 表示加密算法工作模式;EXTEND_SIZE 表示加密算法最大扩展长度,即密文相对于明文一次加密最大扩展的长度,通常可以认为是一次加密(密文-明文)的最大值。

返回值:

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

注意

当获取失败时,将使用参数的默认值。WORK_MODE默认值为0;EXTEND_SIZE 默认值为通过cipher_get_info获得的kh_size。
当同时使用cipher_get_info_ex和cipher_get_para对work_mode进行正确赋值时,最终结果为cipher_get_para所设置的值。

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 提供的第三方加密算法

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

DM 提供了一些第三方加密和散列算法供用户使用,例如:SM3、SM4 算法。第三方加密和散列算法的动态库文件为位于 bin/external_crypto_libs 文件夹下的 openssl1.1.1_crypto.dll(Windows 操作系统)或 libopenssl_crypto.so(Linux 操作系统),此动态库依赖于 bin 文件夹下的 libeay32.dll(Windows 操作系统)或 libcrypto.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 文件夹下的文件进行支持,因此也可以通过查询动态视图 V$external_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 算法。

SM3 为散列算法,与 DM 内置的散列算法用途一致,可以用于完整性校验。SM4 为分组加密算法,与 DM 内置的分组加密算法用途一致,可以用于通信加密、存储加密等场景。

其中,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
微信扫码
分享文档
扫一扫
联系客服