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     - How to protect your eyes automatically adjust the screen brightness on Linux (Linux)

- Apache Tomcat integration and resin (Server)

- Print Linux system error codes (Linux)

- VMware clone Linux find eth0 (Linux)

- Ubuntu 14.04 Trusty Tahr User How to install Banshee 2.9.1 (Linux)

- MySQL + Corosync + Pacemaker + DRBD build highly available MySQL (Server)

- Practical top command (Linux)

- Embedded Linux to solve the problem in the time zone (Linux)

- MBR partitions under Linux (Linux)

- Spark read more HBase tables a RDD (Server)

- Spring AOP (Programming)

- Use PXE with kickstart to install Linux automatically (Linux)

- Git large file storage will help handle large binary files (Linux)

- Ubuntu and derivative users to install the system launcher SimDock 1.3 (Linux)

- Bash variable expansion modifier (Programming)

- CentOS iptables firewall configuration (Linux)

- Linux environment variable configuration and save places (Linux)

- Nginx reverse proxy and self-signed https (Server)

- Oracle 11g partition maintenance (two) - Coalescing Partitions (Database)

- Compare several ways to transfer files between Linux hosts (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:      
 
- The Java utility, JavaMail (Programming)
- Apache Spark1.1.0 deployment and development environment to build (Server)
- KVM installation under CentOS 5.5 (Linux)
- OpenvSwitch 2.1.2 shell script to start and stop (Linux)
- ORA-12547: TNS: lost contact error Solution (Database)
- Linux command ls (Linux)
- Binary tree traversal recursive and non-recursive (cyclic) traversal achieve (Programming)
- iOS in the event delivery and the responder chain (Programming)
- OpenNMS compile under Linux (Server)
- Puppet installation and testing (Server)
- Type Linux commands (Linux)
- System Safety: Windows and Linux platforms (Linux)
- RedHat / CentOS ext4 partition can not be formatted large supplementary ext4 formatting (Linux)
- Linux host dual LAN transceiver package ARP problem (Linux)
- Check the Linux server performance with ten or so commands in a minute (Server)
- RHEL 6.6 install GNOME desktop environment (Linux)
- How to merge two pictures in Cacti (Linux)
- Android basics summary article (Programming)
- Linux start the process (Linux)
- Reset CentOS / RHEL root account password 7 (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.