数据库安全·开发加密插件
时间:2022-05-03
本文章向大家介绍数据库安全·开发加密插件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
以下节选择《Netkiller Architect 手札》
作者:netkiller
地址 http://www.netkiller.cn/architect/
接下来几周的话题是数据库安全。
5.9. 开发加密插件开发
数据库内部提供的摘要函数MD5/SHA/CRC与现有的AES/DES加密函数以及不能满足我们的需求,所以我们有必要开发外挂插件实现数据加密。
这里有一个例子,是我早年开发的 https://github.com/netkiller/mysql-safenet-plugin 这个UDF是链接 Safenet设备,实现数据库加密记录。
saftnet.h
my_bool safenet_encrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *safenet_encrypt(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
void safenet_encrypt_deinit(UDF_INIT *initid);
my_bool safenet_decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *safenet_decrypt(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
void safenet_decrypt_deinit(UDF_INIT *initid);
my_bool safenet_config_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *safenet_config(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
void safenet_config_deinit(UDF_INIT *initid);
safenet.c
/*
Homepage: http://netkiller.github.io/
Author: netkiller<netkiller@msn.com>
*/
#include <mysql.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include "safenet.h"
#define SAFENET_URL "http://localhost/safe/interface"
#define SAFENET_KEY "Web01-key"
char *safe_url;
char *safe_key;
void get_safenet_env(){
if (getenv("SAFENET_URL")){
safe_url = getenv("SAFENET_URL");
}else{
safe_url = SAFENET_URL;
}
if (getenv("SAFENET_KEY")){
safe_key = getenv("SAFENET_KEY");
}else{
safe_key = SAFENET_KEY;
}
}
/* CURL FUNCTION BEGIN*/
struct string {
char *ptr;
size_t len;
};
void init_string(struct string *s) {
s->len = 0;
s->ptr = malloc(s->len+1);
if (s->ptr == NULL) {
fprintf(stderr, "malloc() failedn");
exit(EXIT_FAILURE);
}
s->ptr[0] = ' ';
}
size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
size_t new_len = s->len + size*nmemb;
s->ptr = realloc(s->ptr, new_len+1);
if (s->ptr == NULL) {
fprintf(stderr, "realloc() failedn");
exit(EXIT_FAILURE);
}
memcpy(s->ptr+s->len, ptr, size*nmemb);
s->ptr[new_len] = ' ';
s->len = new_len;
return size*nmemb;
}
char * safenet(char *url, char *mode, char *key, char *in )
{
CURL *curl;
CURLcode res;
char *fields;
char *data;
// curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
struct string s;
init_string(&s);
asprintf(&fields, "mode=%s&keyname=%s&input=%s", mode, key, in);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "safenet/1.0 by netkiller <netkiller@msn.com>");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %sn",
curl_easy_strerror(res));
asprintf(&data, "%s", s.ptr);
//printf("Encrypt: %sn", data);
free(s.ptr);
/* always cleanup */
curl_easy_cleanup(curl);
}
else{
strcpy(data,"");
}
return data;
//curl_global_cleanup();
}
/* CURL FUNCTION END*/
/* ------------------------ safenet encrypt ----------------------------- */
my_bool safenet_encrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1)
{
strncpy(message,
"two arguments must be supplied: safenet_encrypt('<data>').",
MYSQL_ERRMSG_SIZE);
return 1;
}
get_safenet_env();
args->arg_type[0]= STRING_RESULT;
return 0;
}
char *safenet_encrypt(UDF_INIT *initid, UDF_ARGS *args,
__attribute__ ((unused)) char *result,
unsigned long *length,
__attribute__ ((unused)) char *is_null,
__attribute__ ((unused)) char *error)
{
char *data;
data = safenet(safe_url, "encrypt", safe_key, args->args[0]);
*length = strlen(data);
return ((char *)data);
}
void safenet_encrypt_deinit(UDF_INIT *initid)
{
return;
}
/* ------------------------ safenet decrypt ----------------------------- */
my_bool safenet_decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1)
{
strncpy(message,
"two arguments must be supplied: safenet_decrypt('<data>').",
MYSQL_ERRMSG_SIZE);
return 1;
}
get_safenet_env();
args->arg_type[0]= STRING_RESULT;
return 0;
}
char *safenet_decrypt(UDF_INIT *initid, UDF_ARGS *args,
__attribute__ ((unused)) char *result,
unsigned long *length,
__attribute__ ((unused)) char *is_null,
__attribute__ ((unused)) char *error)
{
char *data;
if(strlen(args->args[0]) != 512){
data = args->args[0];
}else{
data = safenet(safe_url, "decrypt", safe_key, args->args[0]);
}
*length = strlen(data);
return ((char *)data);
}
void safenet_decrypt_deinit(UDF_INIT *initid)
{
return;
}
/* ------------------------ safenet config ----------------------------- */
my_bool safenet_config_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
get_safenet_env();
return 0;
}
char *safenet_config(UDF_INIT *initid, UDF_ARGS *args,
__attribute__ ((unused)) char *result,
unsigned long *length,
__attribute__ ((unused)) char *is_null,
__attribute__ ((unused)) char *error)
{
char *config;
asprintf(&config, "SAFENET_URL=%s, SAFENET_KEY=%s", safe_url, safe_key);
*length = strlen(config);
return ((char *)config);
}
void safenet_config_deinit(UDF_INIT *initid)
{
return;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
PROJECT(safenet)
ADD_LIBRARY(safenet SHARED safenet.c)
INCLUDE_DIRECTORIES(/usr/include/mysql)
TARGET_LINK_LIBRARIES(safenet curl)
INSTALL(PROGRAMS libsafenet.so DESTINATION /usr/lib64/mysql/plugin/)
Installation Plugin
yum install -y libcurl-devel
cd src
cmake .
make
make install
cat > /etc/sysconfig/mysqld <<EOF
export SAFENET_URL=http://host.localdomain/safe/interface
export SAFENET_KEY=Web01-key
EOF
Create Function
create function safenet_encrypt returns string soname 'libsafenet.so';
create function safenet_decrypt returns string soname 'libsafenet.so';
create function safenet_config returns string soname 'libsafenet.so';
Example
mysql> select safenet_encrypt('Helloworld!!!');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| safenet_encrypt('Helloworld!!!') |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 994BAB7BC417F0559A09ECE94EDCB695AC1D5705F7ABA9F3562158F5AFAC4720FA9B3E53F30DF65C1726E0F02A93A9CAE7E486349F41AE4F504DC2B49F809C5AF77FEF4DE49D03D8DEC4000B15F2F2A2296500AA6159491E65DEFDFE75FB2E79D31D9BF0CC67932ADA212C34C0B04BF30F222102FAD857F440404C0FE92B8626EA3126B0B5A4FA0B1D09F1CC9EF45EBB6A72123AE82D39F659C717A5AA4F7FB5BDBBC7977C7021F61BBC26B9DB78C9A8657C6BC291CAE5C07F9DF485D71A1E9CC8888793B03BB5AF2DDB57AAEFB6D2EA569226651092414F96BA0880B35B0D8A01A1F7B82C308A2316D07C0FD4E0A298ECB33F4E4EB9F1A1E53760B0BFBE7449 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.58 sec)
mysql> select safenet_decrypt(safenet_encrypt('Helloworld!!!'));
+---------------------------------------------------+
| safenet_decrypt(safenet_encrypt('Helloworld!!!')) |
+---------------------------------------------------+
| Helloworld!!! |
+---------------------------------------------------+
1 row in set (0.31 sec)
mysql> select safenet_config();
Drop Function
drop function safenet_encrypt;
drop function safenet_decrypt;
drop function safenet_config;
- 万达网科裁员95% 王健林曾宣布要在2020年整体上市
- Linq学习笔记(三)
- Go语言cmd命令通过管道实现交互
- 三撩Python
- linq学习笔记(二)
- 盘点2017十大科学突破,让孩子与未来相遇
- ASP.NET 2.0 中的异步页[来自MSDN]
- 温习sql语句中JOIN的各种操作(SQL2005环境)
- 揭开ps的神秘面纱——初步认识photoshop
- 地理坐标系与投影坐标系的区别
- ExtJs学习笔记(6)_可分页的GridPanel
- PowerDesinger联系的定义及使用
- Gis链接
- TortoiseSVN文件夹及文件图标不显示解决方法 TortoiseSVN文件夹及文件图标不显示解决方法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- vuedraggable实现列表拖动排序
- 在 Xcode 中添加 Swift package 依赖
- 浅谈JavaScript中的apply,call和bind
- Git 的简单使用
- 移动端适配
- 《Algorithms Unlocked》读书笔记1——循环和递归
- 《Algorithms Unlocked》读书笔记2——二分查找和排序算法
- 《Algorithms Unlocked》读书笔记3——计数排序
- vue-element-admin
- 二叉树的递归算法
- mongoDB基本操作
- 一个 Vue + Node + MongoDB 博客系统
- promise 和 async 的用法
- 解决 iPhone 微信 H5 无法自动播放音乐问题
- Sequelize 基本操作