C++ mysql udf响应是随机的

C++ mysql udf响应是随机的,c++,mysql,C++,Mysql,我使用相同的参数调用函数AES\u Dec。在大多数情况下,它返回正确的响应。但在15%左右的随机性下,反应是不同的 char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error) { //initialize variables //initialize key char *keyPlain = args-&g

我使用相同的参数调用函数
AES\u Dec
。在大多数情况下,它返回正确的响应。但在15%左右的随机性下,反应是不同的

char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error)
{
    //initialize variables
    //initialize key
    char *keyPlain = args->args[1];
    int keylength = (static_cast<int>(args->lengths[1])) / 2;
    uint16_t *key = new uint16_t;
    hex2bin(keyPlain, reinterpret_cast<unsigned char*>(key));

    //output
    char *output = new char;
    bin2hex(key , keylength, output);
    *length = keylength* 2;
    return output;
}

void hex2bin(const char* src, unsigned char* target)
{
    while (*src && src[1])
    {
        *(target++) = char2int(*src) * 16 + char2int(src[1]);
        src += 2;
    }
}

int char2int(char input)
{
    if (input >= '0' && input <= '9')
        return input - '0';
    if (input >= 'A' && input <= 'F')
        return input - 'A' + 10;
    if (input >= 'a' && input <= 'f')
        return input - 'a' + 10;
    return 0;
}

void bin2hex(unsigned short* pv, size_t len, char *output)
{
    const unsigned char * buf = reinterpret_cast<const unsigned char*>(pv);
    static const char* hex_lookup = "0123456789ABCDEF";
    char *p = output;
    for (int i = 0; i < len; i++) {
        *p++ = hex_lookup[buf[i] >> 4];
        *p++ = hex_lookup[buf[i] & 0x0F];
    }
    *p = '\0';
}
大多数情况下返回的正确响应是:

B99DD1D646CDBC8505419D069B5C0209

随机出现的反应是

B23233323333333332

只有这两种反应。我不知道为什么会出现随机响应。在控制台应用程序中,一切正常,没有任何问题。所以代码应该是有效的

有人有解决办法吗

多谢各位

编辑:完整查询代码:

#include "Header.h"

#ifdef HAVE_DLOPEN

my_bool AES_Dec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3) {
        return 1;
    }
    else if (args->arg_type[0] != STRING_RESULT ||
        args->arg_type[1] != STRING_RESULT ||
        args->arg_type[2] != STRING_RESULT) {
        return 1;
    }
    return 0;
}
void AES_Dec_clear(UDF_INIT *initid, char *is_null, char *message) {
}

void AES_Dec_add(UDF_INIT *initid, UDF_ARGS *args,
    char *is_null, char *message) {
}

char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error)
{
    //initialize variables
    //initialize modus
    char* modChar = args->args[2];
    int mod;
    if (modChar[0] == '1')
        mod = 1;
    else
        mod = 0;

    //initialize key
    char *keyPlain = args->args[1];
    int keylength = (static_cast<int>(args->lengths[1])) / 2;
    uint16_t *key = new uint16_t;
    hex2bin(keyPlain, reinterpret_cast<unsigned char*>(key));

    //initialize value
    const char *plain = args->args[0];
    int plainLength = 0;
    if (mod == 0)
        plainLength = args->lengths[0] / 2;
    else
        plainLength = args->lengths[0] / 2 - 16;
    uint16_t *contentWithIv = new uint16_t;
    uint16_t *iv = new uint16_t;
    hex2bin(plain, (unsigned char*)contentWithIv);
    if (mod == 1) {
        for (int i = 0; i < 8; i++) {
            iv[i] = *contentWithIv;
            contentWithIv++;
        }
    }
    else
        iv == NULL;
    uint16_t *plaintext = contentWithIv;

    // Buffer for the decrypted text 
    uint16_t *decryptedtext = new uint16_t;

    int decryptedtext_len, ciphertext_len;

    // Initialise the library
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    OPENSSL_config(NULL);

    // Encrypt the plaintext 
    decryptedtext_len = decrypt((unsigned char*)plaintext, plainLength, (unsigned char*)key, (unsigned char*)iv, (unsigned char*)decryptedtext, keylength * 8, mod);

    // Add a NULL terminator. We are expecting printable text 
    decryptedtext[decryptedtext_len] = '\0';

    // Clean up 
    EVP_cleanup();
    ERR_free_strings();

    char *finalDec = (char*)malloc(decryptedtext_len * 2);
    bin2hex(decryptedtext, decryptedtext_len, finalDec);

    *length = decryptedtext_len * 2;
    return finalDec; 
}

void AES_Dec_deinit(UDF_INIT *initid) {
    free(initid->ptr);
}

void handleErrors(void) {
    ERR_print_errors_fp(stderr);
    abort();
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext, int keylength, int mod)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int plaintext_len;

    // Create and initialise the context 
    if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    // Initialise the decryption operation. 
    if (mod == 0) {
        if (keylength == 128)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
                handleErrors();
        if (keylength == 192)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL))
                handleErrors();
        if (keylength == 256)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
                handleErrors();
    }
    else if (mod == 1) {
        if (keylength == 128)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
                handleErrors();
        if (keylength == 192)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_cbc(), NULL, key, iv))
                handleErrors();
        if (keylength == 256)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
                handleErrors();
    }
    else
        handleErrors();

    // Provide the message to be decrypted, and obtain the plaintext output.

    if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        handleErrors();
    plaintext_len = len;

    // Finalise the decryption. 
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
    plaintext_len += len;

    // Clean up
    EVP_CIPHER_CTX_free(ctx);

    return plaintext_len;
}

void hex2bin(const char* src, unsigned char* target)
{
    while (*src && src[1])
    {
        *(target++) = char2int(*src) * 16 + char2int(src[1]);
        src += 2;
    }
}

int char2int(char input)
{
    if (input >= '0' && input <= '9')
        return input - '0';
    if (input >= 'A' && input <= 'F')
        return input - 'A' + 10;
    if (input >= 'a' && input <= 'f')
        return input - 'a' + 10;
    return 0;
}

void bin2hex(unsigned short* pv, size_t len, char *output)
{
    const unsigned char * buf = reinterpret_cast<const unsigned char*>(pv);
    static const char* hex_lookup = "0123456789ABCDEF";
    char *p = output;
    for (int i = 0; i < len; i++) {
        *p++ = hex_lookup[buf[i] >> 4];
        *p++ = hex_lookup[buf[i] & 0x0F];
    }
    *p = '\0';
}

#endif /* HAVE_DLOPEN */ 
#包括“Header.h”
#如果DEF已打开
my_bool AES_Dec_init(UDF_init*initid,UDF_ARGS*ARGS,char*message){
如果(参数->参数计数!=3){
返回1;
}
如果(参数->参数类型[0]!=字符串结果||
参数->参数类型[1]!=字符串结果||
参数->参数类型[2]!=字符串结果){
返回1;
}
返回0;
}
void AES_Dec_clear(UDF_INIT*initid,char*为空,char*消息){
}
void AES_Dec_add(UDF_INIT*initid,UDF_ARGS*ARGS,
char*为空,char*消息){
}
char*AES_Dec(UDF_INIT*initid,UDF_ARGS*ARGS,char*结果,无符号长*长度,char*为空,char*错误)
{
//初始化变量
//初始化方式
char*modChar=args->args[2];
整数模;
if(modChar[0]=“1”)
mod=1;
其他的
mod=0;
//初始化密钥
char*keyplane=args->args[1];
int keylength=(静态施法(参数->长度[1])/2;
uint16\u t*键=新uint16\u t;
hex2bin(钥匙平原,重新解释铸造(钥匙));
//初始化值
常量字符*plain=args->args[0];
整数长度=0;
如果(mod==0)
plainLength=args->Length[0]/2;
其他的
plainLength=args->Length[0]/2-16;
uint16\u t*contentWithIv=新uint16\u t;
uint16\u t*iv=新uint16\u t;
hex2bin(普通,(无符号字符*)内容与IV);
如果(mod==1){
对于(int i=0;i<8;i++){
iv[i]=*满足于iv;
contentWithIv++;
}
}
其他的
iv==NULL;
uint16_t*纯文本=满足IV;
//解密文本的缓冲区
uint16\u t*decryptedtext=新uint16\u t;
整数解密文本,密文;
//初始化库
错误加载加密字符串();
OpenSSL_添加_所有算法();
OPENSSL_配置(空);
//加密明文
decryptedtext_len=解密((无符号字符*)明文,明文长度,(无符号字符*)密钥,(无符号字符*)iv,(无符号字符*)decryptedtext,密钥长度*8,mod);
//添加空终止符。我们需要可打印文本
decryptedtext[decryptedtext_len]='\0';
//清理
EVP_cleanup();
ERR_free_strings();
char*finalDec=(char*)malloc(解密文本*2);
bin2hex(解密文本、解密文本、最终文本);
*长度=解密文本长度*2;
返回最终版本;
}
无效AES_Dec_deinit(UDF_INIT*initid){
免费(initid->ptr);
}
无效句柄错误(无效){
错误打印错误fp(stderr);
中止();
}
整数解密(无符号字符*密文,整数密文,无符号字符*密钥,无符号字符*iv,无符号字符*明文,整数密钥长度,整数模)
{
EVP_CIPHER_CTX*CTX;
内伦;
int纯文本;
//创建并初始化上下文
如果(!(ctx=EVP_CIPHER_ctx_new())句柄错误();
//初始化解密操作。
如果(mod==0){
if(keylength==128)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_128_ecb(),NULL,key,NULL))
handleErrors();
if(keylength==192)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_192_ecb(),NULL,key,NULL))
handleErrors();
if(keylength==256)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_256_ecb(),NULL,key,NULL))
handleErrors();
}
否则如果(mod==1){
if(keylength==128)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_128_cbc(),NULL,key,iv))
handleErrors();
if(keylength==192)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_192_cbc(),NULL,key,iv))
handleErrors();
if(keylength==256)
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_256_cbc(),NULL,key,iv))
handleErrors();
}
其他的
handleErrors();
//提供要解密的消息,并获得明文输出。
if(1!=EVP_DecryptUpdate(ctx、明文和len、密文、密文_len))
handleErrors();
明文_len=len;
//完成解密。
如果(1!=EVP_decryptofinal_ex(ctx,明文+len,&len))handleErrors();
明文_len+=len;
//清理
无密码(CTX)的执行副总裁;
返回纯文本;
}
void hex2bin(常量字符*src,无符号字符*target)
{
而(*src&&src[1])
{
*(target++)=char2int(*src)*16+char2int(src[1]);
src+=2;
}
}
int char2int(字符输入)
{
如果(输入>='0'&&input='A'&&input='A'&&input>4];
*p++=hex_查找[buf[i]&0x0F];
}
*p='\0';
}
#endif/*已打开*/

您不应该编写自己的加密函数。这是一个可怕的想法,可能会给您的应用程序带来严重的安全问题。请使用现有的受信任AES算法实现,例如。我使用OpenSSL库进行实际解密。这只是从十六进制字符串到字节再到十六进制字符串的转换。在这个转换中它失败了,而不是实际的算法。你能提供一个完全有效的例子吗?如果没有一个好的简单有效的例子,很难猜出什么是错的。我刚刚添加了完整的代码。我希望你能找到问题所在。让我换一句话:你能提供编译和再现问题的最少代码量吗?
#include "Header.h"

#ifdef HAVE_DLOPEN

my_bool AES_Dec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3) {
        return 1;
    }
    else if (args->arg_type[0] != STRING_RESULT ||
        args->arg_type[1] != STRING_RESULT ||
        args->arg_type[2] != STRING_RESULT) {
        return 1;
    }
    return 0;
}
void AES_Dec_clear(UDF_INIT *initid, char *is_null, char *message) {
}

void AES_Dec_add(UDF_INIT *initid, UDF_ARGS *args,
    char *is_null, char *message) {
}

char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error)
{
    //initialize variables
    //initialize modus
    char* modChar = args->args[2];
    int mod;
    if (modChar[0] == '1')
        mod = 1;
    else
        mod = 0;

    //initialize key
    char *keyPlain = args->args[1];
    int keylength = (static_cast<int>(args->lengths[1])) / 2;
    uint16_t *key = new uint16_t;
    hex2bin(keyPlain, reinterpret_cast<unsigned char*>(key));

    //initialize value
    const char *plain = args->args[0];
    int plainLength = 0;
    if (mod == 0)
        plainLength = args->lengths[0] / 2;
    else
        plainLength = args->lengths[0] / 2 - 16;
    uint16_t *contentWithIv = new uint16_t;
    uint16_t *iv = new uint16_t;
    hex2bin(plain, (unsigned char*)contentWithIv);
    if (mod == 1) {
        for (int i = 0; i < 8; i++) {
            iv[i] = *contentWithIv;
            contentWithIv++;
        }
    }
    else
        iv == NULL;
    uint16_t *plaintext = contentWithIv;

    // Buffer for the decrypted text 
    uint16_t *decryptedtext = new uint16_t;

    int decryptedtext_len, ciphertext_len;

    // Initialise the library
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    OPENSSL_config(NULL);

    // Encrypt the plaintext 
    decryptedtext_len = decrypt((unsigned char*)plaintext, plainLength, (unsigned char*)key, (unsigned char*)iv, (unsigned char*)decryptedtext, keylength * 8, mod);

    // Add a NULL terminator. We are expecting printable text 
    decryptedtext[decryptedtext_len] = '\0';

    // Clean up 
    EVP_cleanup();
    ERR_free_strings();

    char *finalDec = (char*)malloc(decryptedtext_len * 2);
    bin2hex(decryptedtext, decryptedtext_len, finalDec);

    *length = decryptedtext_len * 2;
    return finalDec; 
}

void AES_Dec_deinit(UDF_INIT *initid) {
    free(initid->ptr);
}

void handleErrors(void) {
    ERR_print_errors_fp(stderr);
    abort();
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext, int keylength, int mod)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int plaintext_len;

    // Create and initialise the context 
    if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    // Initialise the decryption operation. 
    if (mod == 0) {
        if (keylength == 128)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
                handleErrors();
        if (keylength == 192)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL))
                handleErrors();
        if (keylength == 256)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
                handleErrors();
    }
    else if (mod == 1) {
        if (keylength == 128)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
                handleErrors();
        if (keylength == 192)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_cbc(), NULL, key, iv))
                handleErrors();
        if (keylength == 256)
            if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
                handleErrors();
    }
    else
        handleErrors();

    // Provide the message to be decrypted, and obtain the plaintext output.

    if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        handleErrors();
    plaintext_len = len;

    // Finalise the decryption. 
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
    plaintext_len += len;

    // Clean up
    EVP_CIPHER_CTX_free(ctx);

    return plaintext_len;
}

void hex2bin(const char* src, unsigned char* target)
{
    while (*src && src[1])
    {
        *(target++) = char2int(*src) * 16 + char2int(src[1]);
        src += 2;
    }
}

int char2int(char input)
{
    if (input >= '0' && input <= '9')
        return input - '0';
    if (input >= 'A' && input <= 'F')
        return input - 'A' + 10;
    if (input >= 'a' && input <= 'f')
        return input - 'a' + 10;
    return 0;
}

void bin2hex(unsigned short* pv, size_t len, char *output)
{
    const unsigned char * buf = reinterpret_cast<const unsigned char*>(pv);
    static const char* hex_lookup = "0123456789ABCDEF";
    char *p = output;
    for (int i = 0; i < len; i++) {
        *p++ = hex_lookup[buf[i] >> 4];
        *p++ = hex_lookup[buf[i] & 0x0F];
    }
    *p = '\0';
}

#endif /* HAVE_DLOPEN */