The foreword 0.

Before writing an article about MD5 digest algorithm, many old iron said can give an article about encryption?

C language to achieve MD5, so simple!

“No” is not a word in the dictionary of yijun! Must be arranged!

For some basic concepts of encryption, you can refer to the following article: Introduction to Public Key Cryptography

In this article, Ejun takes you to implement a simple but also very practical encryption method,

Let everyone understand the actual project development process of data encryption.

One, a common network communication encryption process

There are many encryption algorithms, and the actual implementation process varies greatly,

The following figure shows a common application scenario of network communication encryption.

Password machine some instructions:

  • The password machine can be set on both client and server (it can be software or hardware, as long as the key can be generated)
  • Both keygen and sync codes affect the key sequence generated by the cipher machine
  • The cipher machine will generate the same key sequence when the keygen and the synchronization code are the same. The encryption and decryption parties need to remember the sequence of generating the key and apply for the number of keys when decrypting the data

As shown in the figure above, the server and client communication model based on C/S architecture,

The following describes the C/S interaction process if the client wants to send an encrypted ciphertext to the server.

1 The server sends the key ciphertext

  • First, both the server and client keep a default key
  • The server randomly generates the keygen and encrypts the keygen with the default key to generate the key ciphertext
  • The client can periodically request the key ciphertext by running commands or the server can periodically deliver the key
  • After receiving the ciphertext, the client can decrypt the plaintext keygen using the default key

2. The client encrypts data

  • Before sending data, the client generates a synchronization code
  • Set the synchronization code and keygen to the cipher machine, and then apply to the cipher machine for a certain length of the key
  • The plaintext and key are encrypted by an algorithm (usually xOR) to generate ciphertext

3. The client sends the synchronization code and ciphertext

  • The client sends data ciphertext and synchronization code plaintext to the server
  • The server extracts the synchronization code

4. The server receives data and decrypts it

  • The server sets the keygen and sync code to the cipher machine and applies for a certain number of keys
  • The server decrypts the ciphertext based on the key to obtain the plaintext

Since both the server and client are using the same keygen and synchronization code, the key sequence must be the same.

Second, function implementation

The following are some function prototypes and functional descriptions of the encryption algorithm implemented by Ejun. These functions basically achieve the function of the first section.

1. Apply for the encryption key function request_key

int request_key(int sync,int key_num,char key[])If a new keygen is not set, the generated passwords will be generated sequentially. Each application for a key will record the offset of the last generated key. The next application will continue to allocate the key from the previous position. Key_num: indicates the number of applied keys. Key: indicates the cache of applied key stores. Returned value: Indicates the actual number of returned keysCopy the code

2. Set the key sequence function set_keygen

void set_keygen(int key)Run the following command to set keygen for the cipher machine. Parameter: key: Key Returned value: noneCopy the code

3. Generate random number born_seed

int born_seed(int sync,int key)Run the following command to generate a random key seed based on the synchronization code and keyGen: sync: synchronization code key: returned value: seedCopy the code

4. Reset_keygen ()

void reset_keygen(a)Function: Reset keyGen, will affect the generated random number sequenceCopy the code

Test code examples

The final document is as follows:

key.c  key.h  main.c
Copy the code

Example 1 examines the resulting random sequence

int main(int argc, char *argv[])
{
	int i;
	unsigned int len;
	int j, r, key_num;
	unsigned int sync = 0;
	unsigned char key[MAX_KEY_REQUEST];


	key_num = 10;

	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- the default the keygen synchronous code = 0 to produce ciphertext -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - \ n");
	reset_keygen();

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	print_array("Keys 0-9.",key,len);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	print_array("The key 10-19.",key,len);

	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- use the keygen = 1234 synchronous code = 0 produce ciphertext -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - \ n");
	set_keygen(1234);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	print_array("Keys 0-9.",key,len);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	print_array("The key 10-19.",key,len);
}
Copy the code

Execution Result:

-------------- Use the default keygen synchronization code =0Generate the ciphertext ---------------- key09 -: - (10]
a5 52 c8 14 5d f7 46 5b 89 42The key10- 19: - (10]
38 69 6f a6 08 d2 69 39 cd 29-- -- -- -- -- -- -- -- -- -- -- -- -- -- use the keygen =1234Synchronization code =0Generate the ciphertext ---------------- key09 -: - (10]
0e 83 0b 73 ec f5 4b 4a 74 35The key10- 19: - (10]
e7 f1 06 41 c8 6b aa df 0c 3d 
Copy the code

You can see that the random sequence produced by using different keygen is different.

If you set different synchronization code, the sequence will still be different.

Example 2 uses the default keygen for encryption and decryption

char data0[10] = {0x1.0x2.0x3.0x4.0x5.0x6.0x7.0x8.0x9.0x10};int main(int argc, char *argv[])
{
	int i;
	unsigned int len;
	int j, r, key_num;
	unsigned int sync = 0;
	unsigned char key[MAX_KEY_REQUEST];
	char buf[120] = {0};

	key_num = 10;
	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- the default the keygen to encrypting -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - \ n");
	reset_keygen();
	print_array("\ n clear.",data0,key_num);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	print_array("The key.",key,len);
	for(i=0; i<len; i++) { buf[i] = data0[i]^key[i]; } print_array("\ n cipher text.",buf,len);
	
	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- to decrypt -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- \ n");
	reset_keygen();

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);

	
	for(i=0; i<len; i++) { buf[i] = buf[i]^key[i]; } print_array("\ n clear.",buf,len);
}
Copy the code

The test results

-- -- -- -- -- -- -- -- -- -- -- -- -- -- the default the keygen to encrypting -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - clear: - (10]
01 02 03 04 05 06 07 08 09 10Key: -10]
a5 52 c8 14 5d f7 46 5b 89 42Cipher: - (10]
a4 50 cb 10 58 f1 41 53 80 52-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- to decrypt -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- specifically: - (10]
01 02 03 04 05 06 07 08 09 10 

Copy the code

Example 3 uses different keyGen and sync codes for encryption and decryption

int main(int argc, char *argv[])
{
	int i;
	unsigned int len;
	int j, r, key_num;
	unsigned int sync = 0;
	unsigned char key[MAX_KEY_REQUEST];
	char buf[120] = {0};
	unsigned int mykeygen;


	if(argc ! =4) {
		fprintf(stderr."Usage: %s <seed> <key num> <keygen>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	sync = atoi(argv[1]);
	key_num = atoi(argv[2]);
	mykeygen = atoi(argv[3]);

	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- using the custom the keygen, synchronization code began to encrypted -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - \ n");
	set_keygen(mykeygen);
	print_array("\ n clear.",data0,key_num);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);
	print_array("The key.",key,len);

	for(i=0; i<len; i++) { buf[i] = data0[i]^key[i]; } print_array("\ n cipher text.",buf,len);
	

	printf("\ n -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- to decrypt -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- \ n");
	set_keygen(mykeygen);

	memset(key,0.sizeof(key));
	len = request_key(sync,key_num,key);
	for(i=0; i<len; i++) { buf[i] = buf[i]^key[i]; } print_array("\ n clear.",buf,len);
	exit(EXIT_SUCCESS);
}
Copy the code

The result is as follows:

-- -- -- -- -- -- -- -- -- -- -- -- -- -- using the custom the keygen, synchronization code began to encrypted -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - clear: - (10]
01 02 03 04 05 06 07 08 09 10Key: -10]
53 00 29 cd 27 eb cc 80 1A d7 ciphertext: ----[10]
52 02 2a c9 22 ed cb 88 13C7 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- begin to decrypt -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- specifically: - (10]
01 02 03 04 05 06 07 08 09 10 
Copy the code

So we do realize data encryption and decryption.

The actual use of data encryption

Suppose we use the above example code to port the corresponding functions to both ends of C/S,

Then a complete data encryption and data transmission reference process is as follows:

Remember, as long as both parties set the same keygen and sync code, the cipher machine will spit out the same sequence of keys,

When the client sends a packet, it sends its plaintext synchronization code to the server.

The server can perform decryption based on the keyGen and sync code sent to the client in advance,

Although you can see the sync code in clear text,

But also need to crack the password machine algorithm, the server keyGen ciphertext.

Five, the principle of

The main problem in implementing encryption algorithms is how to generate random sequences as keys.

This example borrows the library function rand() prototype as follows:

#include <stdlib.h>

int rand(void);
Copy the code

The rand() function produces random sequences, but the sequence is the same each time.

#include <stdio.h>

main()
{
	int i = 0;

	for(i=0; i<10; i++) {printf("%d ",rand());
	}
	putchar('\n');
}
Copy the code

The running results are as follows:

peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out 
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421 
peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out 
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421 
Copy the code

What do you do if you want to generate a different random sequence every time? You need the srand() function

void srand(unsigned int seed);
Copy the code

Just set a seed with this function, and the resulting sequence will be completely different,

Usually we seed the return value of time(),

Let’s write some random data here to test the function

#include <stdio.h>

main()
{
	int i = 0;

	srand(111);
	for(i=0; i<10; i++) {printf("%d ",rand());
	}
	putchar('\n');
	srand(1111);
	for(i=0; i<10; i++) {printf("%d ",rand());
	}
	putchar('\n');
}
Copy the code

The result is as follows:

peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out 
1629905861 708017477 1225010071 14444113 324837614 2112273117 1166384513 1539134273 1883039818 779189906 
1383711924 882432674 1555165704 1334863495 1474679554 676796645 154721979 534868285 1892754119 100411878 
Copy the code

So the input of different seeds produces different sequences.

The function prototype is as follows:

The principle of this example is relatively simple, without considering too complex applications (such as multi-key management) and data security,

Only explain the process of encryption and decryption, only as learning to understand the process of encryption and decryption, this encryption algorithm belongs to symmetric encryption, relatively simple, or relatively easy to crack.

At present, the market is by professional companies and teams to achieve encryption and decryption functions.

Bitejun had previously written about a small chat room project,

Implementing Linux Socket Chat room from 0

Behind a gentleman will be based on the encryption mechanism, the chat room all client and server all interactive data encryption processing, please continue to pay attention to: a Linux.

In this paper, the complete code download address: link: pan.baidu.com/s/1VvGNlNGE… Extraction code: O9SE

Background reply: data encryption, you can get all the source code