Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Database \ mysql_config_editor encryption and decryption of the new features of MySQL realization     - Analysis of memory mapping process in Linux x86-32 mode (Linux)

- How to install Kernel 4.0.2 on CentOS 7 (Linux)

- Ubuntu Locale configuration problem solving Can not set LC_CTYPE (Linux)

- CentOS permanently banned from running in the background PackageKit (Linux)

- Debian 8 (amd64) installation deployment Memcached management tools MemAdmin (Server)

- RHEL6.4 x86_64 build SVN service (Server)

- RHEL7.0 environment Linux kernel upgrade (Linux)

- Linux scheduling summary (Linux)

- About Nginx 7 (Server)

- Linux `dirname $ 0` (Linux)

- ORA-30926 and MERGE tables empty the temporary occupation problem (Database)

- Debian GNU / Linux service list acquisition, shutting down services or run (Linux)

- C ++ inheritance and derived (induction principle) (Programming)

- How to enable curl command HTTP2 support (Linux)

- Android studio multi-channel ultra-compact version of the package (Programming)

- 3 tips Linux command (Linux)

- Memcached and Redis (Linux)

- How to use the DM-Crypt encryption Linux File System (Linux)

- Oracle 11g maintenance partitions - Adding Partitions (Database)

- Linux system started to learn: how to view the Linux thread of a process (Linux)

 
         
  mysql_config_editor encryption and decryption of the new features of MySQL realization
     
  Add Date : 2018-11-21      
         
         
         
  AES ECB encryption mysql_config_editor used. ECB block cipher encryption is usually about AES, if you want to encrypt data over block size, you need to fill and chain involving encryption mode, mentioned in the text refers to the chain ECB encryption mode. This article describes the tool uses encryption technology to achieve this, not details of the algorithm confidential technology and implementation details.
The encryption process is as follows:
encrypt_and_write_file-> encrypt_buffer-> my_aes_encrypt

My_aes_encrypt specific implementation is as follows:

int my_aes_encrypt (const char * source, int source_length, char * dest,

const char * key, int key_length)
{
#if defined (HAVE_YASSL)
TaoCrypt :: AES_ECB_Encryption enc;
/ * 128 bit block used for padding * /
uint8 block [MY_AES_BLOCK_SIZE];
int num_blocks; / * number of complete blocks * /
int i;
#elif defined (HAVE_OPENSSL)
MyCipherCtx ctx;
int u_len, f_len;
#endif

/ * The real key to be used for encryption * /
uint8 rkey [AES_KEY_LENGTH / 8];
int rc; / * result codes * /

if ((rc = my_aes_create_key (key, key_length, rkey)))
return rc;

#if defined (HAVE_YASSL)
enc.SetKey ((const TaoCrypt :: byte *) rkey, MY_AES_BLOCK_SIZE);

num_blocks = source_length / MY_AES_BLOCK_SIZE;

for (i = num_blocks; i> 0; i--) / * Encode complete blocks * /
{
enc.Process ((TaoCrypt :: byte *) dest, (const TaoCrypt :: byte *) source,
MY_AES_BLOCK_SIZE);
source + = MY_AES_BLOCK_SIZE;
dest + = MY_AES_BLOCK_SIZE;
}

/ * Encode the rest. We always have incomplete block * /
char pad_len = MY_AES_BLOCK_SIZE - (source_length -
MY_AES_BLOCK_SIZE * num_blocks);
memcpy (block, source, 16 - pad_len);
memset (block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len);

enc.Process ((TaoCrypt :: byte *) dest, (const TaoCrypt :: byte *) block,
MY_AES_BLOCK_SIZE);

return MY_AES_BLOCK_SIZE * (num_blocks + 1);
#elif defined (HAVE_OPENSSL)
if (! EVP_EncryptInit (& ctx.ctx, EVP_aes_128_ecb (),
(Const unsigned char *) rkey, NULL))
return AES_BAD_DATA; / * Error * /
if (! EVP_EncryptUpdate (& ctx.ctx, (unsigned char *) dest, & u_len,
(Unsigned const char *) source, source_length))
return AES_BAD_DATA; / * Error * /
if (! EVP_EncryptFinal (& ctx.ctx, (unsigned char *) dest + u_len, & f_len))
return AES_BAD_DATA; / * Error * /

return u_len + f_len;
#endif
}

The above procedure is mysql using AES confidential process. In Encryption, if mysql defined comes AES encryption algorithm, to use its own (#define HAVE_YASSL). Otherwise OPENSSL EVP is to use the framework of the encryption algorithm.
 
Here OPENSSL EVP encryption algorithm steps:
Click (here) folded or unfolded

int EVP_EncryptInit_ex (EVP_CIPHER_CTX * ctx, const EVP_CIPHER * cipher, ENGINE * impl, const unsigned char * key, const unsigned char * iv)

EVP_EncryptInit (initialization)
              |
              |
              V
 EVP_EncryptUpdate (& ctx, out + len, & outl, in, inl);
 EVP_EncryptUpdate (this is the actual implementation of EVP_EncryptUpdate expressly in accordance with the length of 16 bytes to encrypt, will get to realize the size of the block cipher's (for aes_128 is 16 bytes) and block-size to an integer multiple of encryption. If the input is 50 bytes, only 48 bytes of encrypted here, outl for 48-byte input in the last two bytes are copied to ctx-> buf cached.
For the case inl block_size as an integer multiple of, and ctx-> buf is not directly before the encryption and decryption operations legacy data, save a lot of follow-up)
              |
              |
              V
  EVP_EncryptFinal_ex (& ctx, out + len, & outl);
  For this example, as described, for the first time in addition to the more than two bytes 48 bytes, and the second addressed the first of the remaining 2 bytes and 46 bytes, 100 bytes of input remaining in the last 4 bytes . Here for processing. If not pading, and there is data on the wrong words, otherwise the number of bytes block_size- number of bytes to set a value for this number to be treated, such as block_size = 16, the data length is 4, then the back of 12 bytes set 16-4 = 12, filled after a packet encryption. For the previous time when the whole group is, as the input data is 16 bytes, then call this Final, but is 16 0 encrypts the ciphertext can not, or do not need tune about this Final.
As we know, in encrypted files in, KEY is stored in the file header offset 4bytes where key information is stored after 20bytes. So we just read the key, then the key after the information line by line with the call key decryption program just fine. Specific to achieve the following:
 
algo_aes_ecb.h

#ifndef ALGO_AES_H

#define ALGO_AES_H

int encrypt (unsigned char * plaintext, int plaintext_len, unsigned char * key, unsigned char * ciphertext);

int decrypt (unsigned char * ciphertext, int ciphertext_len, unsigned char * key, unsigned char * plaintext);

#endif

algo_aes_ecb.c


Click (here) folded or unfolded

#include

#include
#include
#include "algo_aes_ecb.h"
#include
#include

typedef unsigned char uint8;
#define AES_KEY_LENGTH 128

uint8 rkey [AES_KEY_LENGTH / 8];

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


static int my_aes_create_key (const char * key, int key_length, uint8 * rkey)
{
uint8 * rkey_end = rkey + AES_KEY_LENGTH / 8;
uint8 * ptr;
const char * sptr;
const char * key_end = key + key_length;

memset (rkey, 0, AES_KEY_LENGTH / 8);

for (ptr = rkey, sptr = key; sptr {
if (ptr == rkey_end)
ptr = rkey;
* Ptr ^ = (uint8) * sptr;
}
}

int encrypt (unsigned char * plaintext, int plaintext_len, unsigned char * key, unsigned char * ciphertext)
{
EVP_CIPHER_CTX * ctx;

int len;

int ciphertext_len;
my_aes_create_key (key, 20, rkey);
/ * Create and initialise the context * /
if ((ctx = EVP_CIPHER_CTX_new ())!) handleErrors ();

/ * Initialise the encryption operation IMPORTANT -. Ensure you use a key
* And IV size appropriate for your cipher
* In this example we are using 128 bit AES (i.e. a 128 bit key).
* /

if (1! = EVP_EncryptInit (ctx, EVP_aes_128_ecb (), (const unsigned char *) rkey, NULL))
handleErrors ();

/ * Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*
* /
if (1! = EVP_EncryptUpdate (ctx, ciphertext, & len, (unsigned const char *) plaintext, plaintext_len))
handleErrors ();
ciphertext_len = len;

/ * Finalise the encryption. Further ciphertext bytes may be written at
* * * This stage.
* * * /
if (! 1 = EVP_EncryptFinal (ctx, ciphertext + len, & len)) handleErrors ();
ciphertext_len + = len;

/ * Clean up * /
EVP_CIPHER_CTX_free (ctx);

return ciphertext_len;
}

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

int len;

int plaintext_len;
my_aes_create_key (key, 20, rkey);

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

/ * Initialise the decryption operation IMPORTANT -. Ensure you use a key
* Size appropriate for your cipher
* In this example we are using 128 bit AES (i.e. a 128 bit key). The
* /

if (1! = EVP_DecryptInit (ctx, EVP_aes_128_ecb (), rkey, NULL))
handleErrors ();

/ * Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*
* /
if (1! = EVP_DecryptUpdate (ctx, plaintext, & len, ciphertext, ciphertext_len))
handleErrors ();
plaintext_len = len;

/ * Finalise the decryption. Further plaintext bytes may be written at
* * * This stage.
* * * /
if (! 1 = EVP_DecryptFinal (ctx, plaintext + len, & len)) handleErrors ();
plaintext_len + = len;

/ * Clean up * /
EVP_CIPHER_CTX_free (ctx);

return plaintext_len;
}

dynstring.h

#ifndef dynstring_h

#define dynstring_h

#include
typedef struct st_dynamic_string
{
char * str;
size_t length, max_length, alloc_increment;
} DYNAMIC_STRING;

#endif

dynstring.c


Click (here) folded or unfolded

#include

#include
#include
#include
#include "dynstring.h"
#define NullS (char *) 0


bool init_dynamic_string (DYNAMIC_STRING * str, const char * init_str, size_t init_alloc, size_t alloc_increment)
{

size_t length;

if (! alloc_increment)
alloc_increment = 128;
length = 1;
if (init_str && (length = strlen (init_str) +1) init_alloc = ((length + alloc_increment-1) / alloc_increment) * alloc_increment;
if (! init_alloc)
init_alloc = alloc_increment;

(! (Str-> str = (char *) malloc (init_alloc))) if return false;
str-> length = length-1;
if (init_str)
memcpy (str-> str, init_str, length);
str-> max_length = init_alloc;
str-> alloc_increment = alloc_increment;

return true;
}


bool dynstr_append_mem (DYNAMIC_STRING * str, const char * append, size_t length)
{
char * new_ptr;
if (str-> length + length> = str-> max_length)
{
size_t new_length = (str-> length + length + str-> alloc_increment) /
str-> alloc_increment;
new_length * = str-> alloc_increment;

if (! (new_ptr = (char *) realloc (str-> str, new_length)))
return true;
str-> str = new_ptr;
str-> max_length = new_length;
}
memcpy (str-> str + str-> length, append, length);
str-> length + = length;
str-> str [str-> length] = 0;
return false;
}

bool dynstr_append (DYNAMIC_STRING * str, const char * append)
{
return dynstr_append_mem (str, append, (uint) strlen (append));
}

bool dynstr_trunc (DYNAMIC_STRING * str, size_t n)
{
str-> length- = n;
str-> str [str-> length] = ' 0';
return false;
}


char * strcend (register const char * s, register char c)
{
for (;;)
{
if (* s == (char) c) return (char *) s;
if (! * s ++) return (char *) s-1;
}
}


bool dynstr_realloc (DYNAMIC_STRING * str, size_t additional_size)
{

(! Additional_size) if return false;
if (str-> length + additional_size> str-> max_length)
{
str-> max_length = ((str-> length + additional_size + str-> alloc_increment-1) /
str-> alloc_increment) * str-> alloc_increment;
if (! (str-> str = (char *) realloc (str-> str, str-> max_length)))
return true;
}
return false;
}


void dynstr_free (DYNAMIC_STRING * str)
{
free (str-> str);
str-> str = NULL;
}

decrypt.c

#include

#include
#include
#include
#include
#include
#include "dynstring.h"
#include "algo_aes_ecb.h"


#define LOGIN_KEY_LEN 20U
#define MY_LINE_MAX 4096
#define MAX_CIPHER_STORE_LEN 4U
#define FN_REFLEN 256

#define O_BINARY 0

typedef unsigned char uchar;
#define MY_LOGIN_HEADER_LEN (4 + LOGIN_KEY_LEN)


#define int4store (T, A) do {* ((char *) (T)) = (char) ((A));
* (((Char *) (T)) + 1) = (char) (((A) >> 8));
* (((Char *) (T)) + 2) = (char) (((A) >> 16));
* (((Char *) (T)) + 3) = (char) (((A) >> 24));
} While (0)

#define sint4korr (A) (int) (((int) ((uchar) (A) [0])) +
(((Int) ((uchar) (A) [1]) << 8)) +
(((Int) ((uchar) (A) [2]) << 16)) +
(((Int) ((uchar) (A) [3]) << 24)))

static char my_key [LOGIN_KEY_LEN];
static char my_login_file [FN_REFLEN];
static int g_fd;
const int access_flag = (O_RDWR | O_BINARY);

static int read_login_key (void)
{

/ * Move past the unused buffer. * /
if (lseek (g_fd, 4, SEEK_SET)! = 4)
exit (1); / * Error while lseeking * /.

if (read (g_fd, (uchar *) my_key, LOGIN_KEY_LEN)! = LOGIN_KEY_LEN)
exit (1);

}

static int read_and_decrypt_file (DYNAMIC_STRING * file_buf)
{

char cipher [MY_LINE_MAX], plain [MY_LINE_MAX];
uchar len_buf [MAX_CIPHER_STORE_LEN];
int cipher_len = 0, dec_len = 0;

/ * Move past key first. * /
if (lseek (g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET)
! = (MY_LOGIN_HEADER_LEN))
goto error; / * Error while lseeking * /.

/ * First read the length of the cipher. * /
while (read (g_fd, len_buf, MAX_CIPHER_STORE_LEN) == MAX_CIPHER_STORE_LEN)
{
cipher_len = sint4korr (len_buf);

if (cipher_len> MY_LINE_MAX)
goto error;

/ * Now read 'cipher_len' bytes from the file. * /
if ((int) read (g_fd, (uchar *) cipher, cipher_len) == cipher_len)
{
if ((dec_len = decrypt (cipher, cipher_len, my_key, plain)) <0)
goto error;

plain [dec_len] = 0;
dynstr_append (file_buf, plain);
}
}

return 0;

error:
printf ( "could not decrypt the file");
return -1;
}


int my_default_get_login_file (char * file_name, size_t file_name_size)
{
size_t rc;

if (getenv ( "MYSQL_TEST_LOGIN_FILE"))
rc = snprintf (file_name, file_name_size, "% s",
getenv ( "MYSQL_TEST_LOGIN_FILE"));

else if (getenv ( "HOME"))
rc = snprintf (file_name, file_name_size, "% s / .mylogin.cnf",
getenv ( "HOME"));
else
{
memset (file_name, 0, file_name_size);
return 0;
}
/ * Anything <= 0 will be treated as error. * /
if (rc <= 0)
return 0;

return 1;
}

int main (int argc, char ** argv) {

DYNAMIC_STRING file_buf;
if (! my_default_get_login_file (my_login_file, sizeof (my_login_file))) {
printf ( "logfile file not found n");
goto error;
}

if ((g_fd = open (my_login_file, access_flag)) == -1)
{
printf ( "could not open the file n");
goto error;
}
init_dynamic_string (& file_buf, "", 256, MY_LINE_MAX);

read_login_key ();

read_and_decrypt_file (& file_buf);
printf ( "% s", file_buf.str);

error:
dynstr_free (& file_buf);
}

the makefile


Click (here) folded or unfolded

OBJ_DIR = ./obj

BIN_DIR = ./bin
SRC_DIR = ./
OBJS =
$ (OBJ_DIR) /algo_aes_ecb.o
$ (OBJ_DIR) /dynstring.o
$ (OBJ_DIR) /decrypt.o
TARGET = decrypt
INC_OPT = -I./
LNK_OPT = -lssl

$ (BIN_DIR) / $ (TARGET): clean chkobjdir chkbindir $ (OBJS)
gcc -g -o $ @ $ (OBJS) $ (LNK_OPT)

$ (OBJ_DIR) /algo_aes_ecb.o: algo_aes_ecb.c
gcc -g $ (INC_OPT) -c -o $ @ $ <

$ (OBJ_DIR) /decrypt.o: decrypt.c
gcc -g $ (INC_OPT) -c -o $ @ $ <

$ (OBJ_DIR) /dynstring.o: dynstring.c
gcc -g $ (INC_OPT) -c -o $ @ $ <

chkobjdir:
! @if Test -d $ (OBJ_DIR);
then
mkdir $ (OBJ_DIR);
fi

chkbindir:
! @if Test -d $ (BIN_DIR);
then
mkdir $ (BIN_DIR);
fi

clean:
rm -rf $ (TARGET)
rm -rf $ (OBJS)

The binary executable file, you can get after the password encryption:

It is only to decrypt the encrypted files by default, the information is encrypted $ HOME / .mylogin.cnf file is stored. If the file is stored in other places, you can modify the code, specify the location file.

to sum up:
From the entire analysis can be seen, mysql_config_editor using AES ECB 128bit encryption algorithm, encryption simple. Furthermore, the encrypted secret key is also stored in an encrypted file beginning. Therefore, if the file is read, it is easy to be decrypted by the key. But compared to the previous version, this feature can prevent at least the command line to enter a password, it is easy to divulge passwords, especially the non-disclosure localhost password so that malicious hackers remote access. Encryption of the program, at least be able to prevent the vast majority of people do not know know the plain text password or encryption policy to prevent those who know the password, thereby reducing the security risks.
     
         
         
         
  More:      
 
- Try debugfs restore the deleted files ext3 file system (Linux)
- Linux Mint 17 set up the Ruby environment (Linux)
- To install Ganglia configuration of experience under CentOS 5.5 (Linux)
- Android use canvas board painting (Programming)
- C ++ runtime environment built on CentOS 6.6 and Oracle database connection (Database)
- How to use Evernote in the Linux command line (Linux)
- How do you access Dropbox Linux command line (Linux)
- RHEL6.5 replace local YUM source (Linux)
- Ubuntu 14.04 installation and configuration environment variable JDK1.8.0_25 (Linux)
- OpenStack package problems and solutions under CentOS6 (Linux)
- Linux package management (Linux)
- MySQL main and backup replication structures (using mysqld_multi) (Database)
- CentOS How to mount the hard drive (Linux)
- Install the Red Hat Container Development Kit on OSX (Server)
- Ubuntu Tutorial - Manually install Oracle Java JDK 8 (Linux)
- Linux account management add relevant directives (Linux)
- Build ASP.NET 5 development environment in Ubuntu (Server)
- Chromium Install Flash Official Guide (Linux)
- Delete specific files using bash directory under Linux (Linux)
- Use dump restore mode fast backup and recovery system FreeBSD (Linux)
     
           
     
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.