mysql udf响应是随机的

时间:2016-03-04 15:29:27

标签: c++ mysql

我用相同的参数调用函数AES_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';
}

我用以下参数调用此函数:

SELECT AES_Dec('2C4E907536FBB3C9FADD4CFBD45950EF03517AA5F7F402DA9E3ABD03FC6E0068EF39F3DFC26A92B871E8D8CE521EAF6C', 'B99DD1D646CDBC8505419D069B5C0209', '1')

大部分时间返回的正确答案是:

  

B99DD1D646CDBC8505419D069B5C0209

随机的回应是

  

B2323332333333323333333333333332

只有这两个回复。我不知道为什么会出现随机响应。在控制台应用程序中,一切正常,没有任何问题。所以代码应该可以工作。

有人有解决方案吗?

谢谢。

编辑:完整的quellcode:

#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 */ 

0 个答案:

没有答案