我用相同的参数调用函数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 */