Toggle navigation
PostgreSQL中文社区
首页
(current)
社区新闻
中文文档
加入ACE
相关资料
了解PostgreSQL
PostgreSQL相关文档
PostgreSQL软件下载
PostgreSQL中文图书
社区年会PPT资料
关于中文社区
注册
登录
全部
Bug
使用技巧
内容问题
建议
系统安装
集群复制
其他
首页
有问有答(FAQ)
【%E6%BA%90%E7%A0%81%E5%BC%80%E5%8F%91】
类主题列表
yiyi99999
用c语言写了一个extension的加密函数 ...
... 2019-04-08 23:10:21+08...1楼
用c语言写了一个extension的加密函数,但是发现用sql获取加密值会变换,这是什么原因啊? test.c #include
#include
#include
#include "postgres.h" #include "fmgr.h" #include "utils/builtins.h" PG_MODULE_MAGIC; #define SM4_ENCRYPT 1 #define SM4_DECRYPT 0 typedef struct { int mode; unsigned long sk[32]; } sm4_context; /* * 32-bit integer manipulation macros (big endian) */ #ifndef GET_ULONG_BE #define GET_ULONG_BE(n,b,i) \ { \ (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ | ( (unsigned long) (b)[(i) + 1] << 16 ) \ | ( (unsigned long) (b)[(i) + 2] << 8 ) \ | ( (unsigned long) (b)[(i) + 3] ); \ } #endif #ifndef PUT_ULONG_BE #define PUT_ULONG_BE(n,b,i) \ { \ (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ (b)[(i) + 3] = (unsigned char) ( (n) ); \ } #endif #define SHL(x,n) (((x) & 0xFFFFFFFF) << n) #define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n))) #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } static const unsigned char SboxTable[16][16] = { {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05}, {0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99}, {0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62}, {0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6}, {0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8}, {0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35}, {0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87}, {0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e}, {0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1}, {0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3}, {0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f}, {0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51}, {0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8}, {0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0}, {0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84}, {0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48} }; static const unsigned long FK[4] = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc}; static const unsigned long CK[32] = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 }; static unsigned char sm4Sbox(unsigned char inch) { unsigned char *pTable = (unsigned char *)SboxTable; unsigned char retVal = (unsigned char)(pTable[inch]); return retVal; } static unsigned long sm4Lt(unsigned long ka) { unsigned long bb = 0; unsigned long c = 0; unsigned char a[4]; unsigned char b[4]; PUT_ULONG_BE(ka, a, 0) b[0] = sm4Sbox(a[0]); b[1] = sm4Sbox(a[1]); b[2] = sm4Sbox(a[2]); b[3] = sm4Sbox(a[3]); GET_ULONG_BE(bb, b, 0) c = bb ^ (ROTL(bb, 2)) ^ (ROTL(bb, 10)) ^ (ROTL(bb, 18)) ^ (ROTL(bb, 24)); return c; } static unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk) { return (x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk)); } static unsigned long sm4CalciRK(unsigned long ka) { unsigned long bb = 0; unsigned long rk = 0; unsigned char a[4]; unsigned char b[4]; PUT_ULONG_BE(ka, a, 0) b[0] = sm4Sbox(a[0]); b[1] = sm4Sbox(a[1]); b[2] = sm4Sbox(a[2]); b[3] = sm4Sbox(a[3]); GET_ULONG_BE(bb, b, 0) rk = bb ^ (ROTL(bb, 13)) ^ (ROTL(bb, 23)); return rk; } static void sm4_setkey( unsigned long SK[32], unsigned char key[16] ) { unsigned long MK[4]; unsigned long k[36]; unsigned long i = 0; GET_ULONG_BE( MK[0], key, 0 ); GET_ULONG_BE( MK[1], key, 4 ); GET_ULONG_BE( MK[2], key, 8 ); GET_ULONG_BE( MK[3], key, 12 ); k[0] = MK[0] ^ FK[0]; k[1] = MK[1] ^ FK[1]; k[2] = MK[2] ^ FK[2]; k[3] = MK[3] ^ FK[3]; for (; i < 32; i++) { k[i + 4] = k[i] ^ (sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i])); SK[i] = k[i + 4]; } } static void sm4_one_round( unsigned long sk[32], unsigned char input[16], unsigned char output[16] ) { unsigned long i = 0; unsigned long ulbuf[36]; memset(ulbuf, 0, sizeof(ulbuf)); GET_ULONG_BE( ulbuf[0], input, 0 ) GET_ULONG_BE( ulbuf[1], input, 4 ) GET_ULONG_BE( ulbuf[2], input, 8 ) GET_ULONG_BE( ulbuf[3], input, 12 ) while (i < 32) { ulbuf[i + 4] = sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], sk[i]); i++; } PUT_ULONG_BE(ulbuf[35], output, 0); PUT_ULONG_BE(ulbuf[34], output, 4); PUT_ULONG_BE(ulbuf[33], output, 8); PUT_ULONG_BE(ulbuf[32], output, 12); } static void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] ) { ctx->mode = SM4_ENCRYPT; sm4_setkey( ctx->sk, key ); } static void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] ) { int i; ctx->mode = SM4_ENCRYPT; sm4_setkey( ctx->sk, key ); for ( i = 0; i < 16; i ++ ) { SWAP( ctx->sk[ i ], ctx->sk[ 31 - i] ); } } static void sm4_crypt_ecb( sm4_context *ctx, int mode, int length, unsigned char *input, unsigned char *output) { while ( length > 0 ) { sm4_one_round( ctx->sk, input, output ); input += 16; output += 16; length -= 16; } } static void sm4_crypt_cbc( sm4_context *ctx, int mode, int length, unsigned char iv[16], unsigned char *input, unsigned char *output ) { int i; unsigned char temp[16]; if ( mode == SM4_ENCRYPT ) { while ( length > 0 ) { for ( i = 0; i < 16; i++ ) output[i] = (unsigned char)( input[i] ^ iv[i] ); sm4_one_round( ctx->sk, output, output ); memcpy( iv, output, 16 ); input += 16; output += 16; length -= 16; } } else { while ( length > 0 ) { memcpy( temp, input, 16 ); sm4_one_round( ctx->sk, input, output ); for ( i = 0; i < 16; i++ ) output[i] = (unsigned char)( output[i] ^ iv[i] ); memcpy( iv, temp, 16 ); input += 16; output += 16; length -= 16; } } } PG_FUNCTION_INFO_V1(crypt_gm_enc); PG_FUNCTION_INFO_V1(crypt_gm_dec); PG_FUNCTION_INFO_V1(test_add_fun); PG_FUNCTION_INFO_V1(test_add_fun1); PG_FUNCTION_INFO_V1(hello_world); PG_FUNCTION_INFO_V1(hello_text_arg); PG_FUNCTION_INFO_V1(hello_ereport); PG_FUNCTION_INFO_V1(test_disp0); PG_FUNCTION_INFO_V1(test_disp1); Datum test_add_fun(PG_FUNCTION_ARGS); Datum test_add_fun1(PG_FUNCTION_ARGS); Datum hello_world(PG_FUNCTION_ARGS); Datum hello_text_arg(PG_FUNCTION_ARGS); Datum hello_ereport(PG_FUNCTION_ARGS); Datum test_disp0(PG_FUNCTION_ARGS); Datum test_disp1(PG_FUNCTION_ARGS); Datum crypt_gm_enc(PG_FUNCTION_ARGS); Datum crypt_gm_dec(PG_FUNCTION_ARGS); Datum test_disp0(PG_FUNCTION_ARGS) { unsigned char plaintext[] = "test1"; unsigned long i; int n; char *hex_string; unsigned char highByte, lowByte; n = strlen((const char *)plaintext); hex_string = palloc(n * 2); for(i=0; i
> 4; lowByte = plaintext[i] & 0x0f; highByte += 0x30; if (highByte > 0x39) { hex_string[i*2] = highByte + 0x07; } else { hex_string[i*2] = highByte; } lowByte += 0x30; if (lowByte > 0x39) { hex_string[i*2+1] = lowByte + 0x07; } else { hex_string[i*2+1] = lowByte; } } PG_RETURN_TEXT_P(cstring_to_text_with_len(hex_string, n * 2)); } Datum test_disp1(PG_FUNCTION_ARGS) { unsigned long i; int n; char *hex_string; unsigned char highByte, lowByte; text *arg0 = PG_GETARG_TEXT_PP(0); char *buff0 = text_to_cstring(arg0); n = strlen((const char *)buff0); hex_string = palloc(n * 2); for(i=0; i
> 4; lowByte = buff0[i] & 0x0f; highByte += 0x30; if (highByte > 0x39) { hex_string[i*2] = highByte + 0x07; } else { hex_string[i*2] = highByte; } lowByte += 0x30; if (lowByte > 0x39) { hex_string[i*2+1] = lowByte + 0x07; } else { hex_string[i*2+1] = lowByte; } } PG_RETURN_TEXT_P(cstring_to_text_with_len(hex_string, n * 2)); } Datum crypt_gm_enc(PG_FUNCTION_ARGS) { unsigned char *plaintext; unsigned char key[16] = {0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0xFB, 0x36, 0xD7, 0xA5, 0xD2, 0x21, 0x6E}; sm4_context ctx; unsigned long i; int n; char *hex_string; unsigned char highByte, lowByte; unsigned char *ciphertext; text *arg0 = PG_GETARG_TEXT_PP(0); char *buff0 = text_to_cstring(arg0); text *arg1 = PG_GETARG_TEXT_PP(1); char *buff1 = text_to_cstring(arg1); if(strlen((const char *)buff1) > 8) { memcpy(key, buff1, 8); } else { memcpy(key, buff1, strlen((const char *)buff1)); } plaintext = palloc0(strlen((const char *)buff0) + 1); memcpy(plaintext, buff0, strlen((const char *)buff0)); pfree(buff0); pfree(buff1); sm4_setkey_enc(&ctx, key); n = ((strlen((const char *)plaintext)/16)+1)*16; ciphertext = palloc0(n); sm4_crypt_ecb(&ctx, 1, strlen((const char *)plaintext), plaintext, ciphertext); pfree(plaintext); sm4_setkey_dec(&ctx, key); plaintext = palloc0(n); sm4_crypt_ecb(&ctx, 0, n, ciphertext, plaintext); hex_string = palloc0(n * 2 + 1); for(i=0; i
> 4; lowByte = ciphertext[i] & 0x0f; highByte += 0x30; if (highByte > 0x39) { hex_string[i*2] = highByte + 0x07; } else { hex_string[i*2] = highByte; } lowByte += 0x30; if (lowByte > 0x39) { hex_string[i*2+1] = lowByte + 0x07; } else { hex_string[i*2+1] = lowByte; } } pfree(ciphertext); //pfree(plaintext); //PG_RETURN_TEXT_P(out); PG_RETURN_TEXT_P(cstring_to_text_with_len(hex_string, n * 2 + 1)); //PG_RETURN_BYTEA_P(ciphertext); } Datum crypt_gm_dec(PG_FUNCTION_ARGS) { unsigned char *plaintext; unsigned char key[16] = {0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0xFB, 0x36, 0xD7, 0xA5, 0xD2, 0x21, 0x6E}; sm4_context ctx; unsigned long i, j; unsigned char *ciphertext; int len; int final_len; text *arg0 = PG_GETARG_TEXT_PP(0); char *buff0 = text_to_cstring(arg0); text *arg1 = PG_GETARG_TEXT_PP(1); char *buff1 = text_to_cstring(arg1); if(strlen((const char *)buff1) > 8) { memcpy(key, buff1, 8); } else { memcpy(key, buff1, strlen((const char *)buff1)); } plaintext = palloc0(strlen((const char *)buff0) + 1); memcpy(plaintext, buff0, strlen((const char *)buff0)); pfree(buff0); pfree(buff1); len = strlen((const char *)plaintext); //IF_ASSERT(len % 2 != 0) // return NULL; final_len = len / 2; ciphertext = palloc(final_len+1); for (i=0, j=0; j
> 4; lowByte = ciphertext[i] & 0x0f; highByte += 0x30; if (highByte > 0x39) { hex_string[i*2] = highByte + 0x07; } else { hex_string[i*2] = highByte; } lowByte += 0x30; if (lowByte > 0x39) { hex_string[i*2+1] = lowByte + 0x07; } else { hex_string[i*2+1] = lowByte; } } pfree(ciphertext); PG_RETURN_TEXT_P(cstring_to_text_with_len(hex_string, n * 2)); } Datum test_add_fun1(PG_FUNCTION_ARGS) { unsigned char *plaintext; unsigned char key[16] = {0x0B, 0x02, 0x01, 0x0B, 0x02, 0x02, 0x02, 0x09, 0x98, 0xFB, 0x36, 0xD7, 0xA5, 0xD2, 0x21, 0x6E}; sm4_context *ctx; unsigned long i; int n; char *hex_string; unsigned char highByte, lowByte; unsigned char *ciphertext; text *arg0 = PG_GETARG_TEXT_PP(0); plaintext = text_to_cstring(arg0); ctx = palloc0(sizeof(sm4_context)); sm4_setkey_enc(ctx, key); n = ((strlen((const char *)plaintext)/16)+1)*16; ciphertext = palloc(n); sm4_crypt_ecb(ctx, 1, strlen((const char *)plaintext), plaintext, ciphertext); hex_string = palloc(n * 2); for(i=0; i
> 4; lowByte = ciphertext[i] & 0x0f; highByte += 0x30; if (highByte > 0x39) { hex_string[i*2] = highByte + 0x07; } else { hex_string[i*2] = highByte; } lowByte += 0x30; if (lowByte > 0x39) { hex_string[i*2+1] = lowByte + 0x07; } else { hex_string[i*2+1] = lowByte; } } pfree(ciphertext); pfree(ctx); PG_FREE_IF_COPY(arg0, 0); PG_RETURN_TEXT_P(cstring_to_text_with_len(hex_string, n * 2)); } Datum hello_world(PG_FUNCTION_ARGS) { PG_RETURN_TEXT_P(cstring_to_text("Hello, World!")); } Datum hello_text_arg(PG_FUNCTION_ARGS) { text *hello = cstring_to_text("Hello, "); int32 hello_sz = VARSIZE(hello) - VARHDRSZ; text *name = PG_GETARG_TEXT_P(0); int32 name_sz = VARSIZE(name) - VARHDRSZ; text *tail = cstring_to_text("!"); int32 tail_sz = VARSIZE(tail) - VARHDRSZ; int32 out_sz = hello_sz + name_sz + tail_sz + VARHDRSZ; text *out = (text *) palloc(out_sz); SET_VARSIZE(out, out_sz); memcpy(VARDATA(out), VARDATA(hello), hello_sz); memcpy(VARDATA(out) + hello_sz, VARDATA(name), name_sz); memcpy(VARDATA(out) + hello_sz + name_sz, VARDATA(tail), tail_sz); PG_RETURN_TEXT_P(out); } Datum hello_ereport(PG_FUNCTION_ARGS) { ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("null value not allowed"))); PG_RETURN_VOID(); } test--1.0.sql /* contrib/test/test--1.0.sql */ --complain if script is sourced in psql rather than via ALTER EXTENSION \echo Use "CRAETE EXTENSION test_tabble" to load this file. \quit CREATE FUNCTION test_add_fun(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'test_add_fun' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION test_add_fun1(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'test_add_fun1' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION crypt_gm_enc(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'crypt_gm_enc' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; CREATE FUNCTION crypt_gm_dec(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'crypt_gm_dec' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; CREATE FUNCTION hello_world() RETURNS text AS 'MODULE_PATHNAME' , 'hello_world' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION hello_text_arg(text) RETURNS text AS 'MODULE_PATHNAME' , 'hello_text_arg' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION hello_ereport() RETURNS void AS 'MODULE_PATHNAME' , 'hello_ereport' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION test_disp0(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'test_disp0' LANGUAGE C STRICT PARALLEL RESTRICTED; CREATE FUNCTION test_disp1(input text, keystr text) /* 创建一个函数 */ RETURNS text AS 'MODULE_PATHNAME' , 'test_disp0' LANGUAGE C STRICT PARALLEL RESTRICTED; 然后执行: create extension test; select test_add_fun1('test1', '99'); 返回值会变,但不是每次都变,这是什么原因啊? 这段代码拿出来在linux下跑值是不会变的。
我的签名:
doudou586
回复: ...
... 2019-09-18 10:49:00+08...2楼
呵呵。。。自己种的Bug只能自己找了(Joking :)。。。这么长,大家一般也看得眼花。。。。反正我是看不懂。。。帮你顶一下吧。。。
我的签名:天天要用的管理软件 -- 坎普ERP软件
您还没有登录,请您登录后再发表回复
© 2010 PostgreSQL中文社区