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     - Construction CA certificate using OpenSSL command line (Server)

- How to experience Unity 8 Mir on Ubuntu 16.04 (Linux)

- To compile and install Clang 3.5.0 in Linux CentOS (Linux)

- Practical Handbook: 130+ improve the efficiency of commonly used commands Vim (Linux)

- Fedora 22 users to install the VLC media player (Linux)

- Oracle 11g R2 RAC RMAN backup script example (Database)

- New features of Java 9 HTTP2 and REPL (Programming)

- Ubuntu rights management common commands (Linux)

- Linux security configuration (Linux)

- Linux server operating system security configuration (Linux)

- Use SocketServer write a sockets program (Programming)

- shell script: the number of characters in the text to print no more than 6 words (Programming)

- Ceph cluster disk is no workaround for the remaining space (Server)

- OpenSUSE 13.1 OpenSUSE 12.3 and how to install Cinnamon 2.2 Desktop (Linux)

- How to create SWAP files in Ubuntu 14.04 (Linux)

- Zabbix monitoring of the switch (Server)

- How to install Linux Kernel 4.0 On CentOS 7 system (Linux)

- Generated characters using Java Videos (Programming)

- Java how to achieve bubble sort the problem Arraylist (Programming)

- C language header file defines a global variable (Programming)

 
         
  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:      
 
- Enterprise Hadoop cluster architecture - Hadoop installation (Server)
- ELKstack log analysis platform (Server)
- VirtualBox modify the size of the virtual machine disk VDI (Linux)
- Linux system components Detailed log (Linux)
- Linux Study of --CentOS create local yum repository (Linux)
- Linux system security check notes on performance (Linux)
- Analysis of memory mapping process in Linux x86-64 mode (Linux)
- Linux-based Heartbeat high availability configuration httpd service (Server)
- CentOS7 install MySQL 5.5 (Database)
- VMware virtual machine to use bridged mode fast Internet access (Linux)
- Difference LVS three scheduling modes (Server)
- Nginx introduced Dynamic Module Architecture (Server)
- Linux / proc directory Comments (Linux)
- Sorting Algorithm (1) Quick Sort C ++ implementation (Programming)
- File sharing and fork function (Programming)
- Dell R710 server disk recovery database one case (record) (Server)
- In-depth understanding of capture Node.js garbage collection and memory leaks (Programming)
- Install apr support for Tomcat on Linux (Server)
- Linux Security (Linux)
- Java code JIT compiler-friendly Mody (Programming)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.