Introduction and implementation of des algorithms (II)

Source: Internet
Author: User

Introduction and implementation of des algorithms (II)
Author: Xi'an Wuzhen

Iii. file encryption and decryption tools

In the introduction and implementation of the DES algorithm (I), this article introduces the principles of the DES algorithm. In this article, we will provide the specific implementation code of a text file encryption tool.

3.1 Introduction to implementation

Using the interface functions encapsulated by the core code of the algorithm, the author has compiled an encryption and decryption tool for text files. The following describes some experiences in practice, hoping to benefit readers.
I chose to write the ciphertext into the file in hexadecimal format. Of course, the file can also be written directly.
Example:
Ciphertext: 12345678
Displayed in memory:
31 32 33 34 35 36 37 38
Write the file in the form of 3132333435363738.
For the convenience of decryption, each byte in the ciphertext is expressed in two bytes, that is, the content displayed as 0x9a in the memory is written into the file in the form of 9A. when the content displayed in the memory is 0x0? (? Represents 0 ~ F) The format must be 0? To write files.
In this way, we can avoid the problem mentioned above, but convert the data read from the file into the ciphertext to be decrypted in sequence according to the principle of the combination of two pairs during decryption.
Example:
The read data is:
3132333435363738
The recovery process is as follows:
31-> 1
32-> 2
33-> 3
....
38-> 8
The real ciphertext 12345678 is obtained, so that the DES algorithm decryption function can be called to obtain the plaintext from the ciphertext.
The DES algorithm encrypts and decrypts data blocks of a fixed size (64-bit). For data blocks that are not 64-bit long enough, the padding mechanism must be used to fill in the data blocks, for ease of use, data bit filling is transparent to users. When using this tool for encryption and decryption, you only need to enter the operation type, the file name to read the data, the file name to write the operation result, and the key.
Operation logic:
# Define read size 512
Steps:
1. Read readfilesize bytes from the file
2. If the number of data read from the file is less than readfilesize, replace it with 0, and then operate the readfilesize data based on the type specified by the user.
3. Check whether the file is complete. If no, perform step 1.
4. Add the actual length of the encrypted file to the end of the ciphertext.
5. End
Reading only readfilesize bytes from a file at a time is used to prevent memory insufficiency due to the large size of the file to be encrypted or decrypted.

3.2 precautions

The encryption key of the DES algorithm is generated based on the password entered by the user, this algorithm uses the 8th, 16th, 24th, 32nd, 40th, 48th, 56th, 64th, and bits in a 64-bit password as the parity bit, ignore these 8 bits when calculating the key. if the entered password is only different in the eight digits, the operation results will be the same.
Example:
The entered password is wuzhenll, and the key's hexadecimal representation is 77 75 7A 68 65 6e 6C 6c
If you change the parity of the 64-bit data, you can obtain 16 different passwords,
After all eight parity test bits are reversed:
W-> V
U-> T
Z-> {
H-> I
E-> d
N-> O
L-> m
New Password: VT {idomm
On the surface, the new password is very different from the original password, but because they only have different parity bits, the results of the encryption and decryption operations with these two passwords are the same.
I suggest using a multi-key encryption and decryption solution with a high security factor.
In addition, the length of the password entered by the user is unlimited. when the length of the entered password is 0, the default 64-bit password is used. When the length of the entered password is greater than 8 bytes, the first 8 bytes of the password are valid passwords.
The tool provides six different operation types:

1: one layer of encryption;
2: layer-1 decryption;

3: layer-n single-key encryption;
4: layer-N Single Key decryption;

5: N-layer multi-key encryption;
6: layer-N multi-Key decryption;

These six operations are symmetric. For example, select one layer for encryption of plaintext, and use one layer for decryption of ciphertext.

3.3 source code

The author provides the source code for implementing the self-developed DES algorithm. Readers can directly use the interface functions to implement encryption and decryption. readers who are interested in self-implementation can also take her as a reference .. if any problem is found, please email me. OK, let's go...

/* Skip the information header, # include file and function declaration */

Ulong32 g_outkey [16] [2] = {0};/* output key */ulong32 g_bufkey [2] = {0};/* form the START key */

/* Table query is usually used for implementation. The following table is defined for search */

Static ulong8 wz_lefttable [16] = {,}; static ulong32 wz_leftandtab [3] = {0x0, 0x80000000, 0xc0000000}; static ulong8 blocks [28] = {, 35, ,}; static ulong8 blocks [28] =, }; static ulong8 blocks [48] =, 47,55, 30,40, 51,45, 33,48, 44,49, 39,56, 34,53, 46,42, 50,36, 29,32}; static ulong8 wz_pc4 [64] ={/ * last adjustment */40,8, 48,16,, 64, 32,, 19,}; static ulong8 wz_pc1 [64] = {/* used for the first conversion */, 50,,, 35, etc.}; static ulong8 blocks [32] =,, 26,}; static ulong32 random [64] = {0x80000000l, random, 0x20000000l, 0x0000000l, 0x8000000l, 0x4000000l, 0x2000000l, 0x000000l, clerk, clerk, 0x200000l, clerk, 0x0000l, clerk, 0x2000l, 0x1000l, 0x800l, 0x400l, 0x200l, 0x100l, 0x80l, 0x40l, 0x20l, 0x10l, 0x8l, 0x4l, 0x2l, 0x1l, large, large, 0x20000000l, 0x0000000l, large, 0x4000000l, 0x2000000l, 0x000000l, large, small, small, 0x100000l, numbers, 0x0000l, numbers, numbers, 0x2000l, 0x1000l, 0x800l, 0x400l, 0x200l, 0x100l, 0x80l, 0x40l, 0x20l, 0x10l, 0x8l, 0x4l, 0x2l, 0x1l,}; static ulong8 exptab3 [48] =, 20, 21, 20, 21, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; static ulong8 SP [8] [64] ={{ 0xe, 0x4, 0xf, 0xd, 0x2, 0xe, 0xf, 0x2, 0xb, 0xd, 0x3, 0xa, 0xa, 0x6, 0x6, 0xc, 0xc, 0xb, 0x5, 0x9, 0x9, 0x5, 0x0 0x3, 0x7, 0 8, 0x4, 0xf, 0x1, 0xc, 0xe, 0x8, 0x8, 0x2, 0xd, 0x4, 0x6, 0x9, 0x2, 0x1, 0xb, 0x7, 0xf, 0x5, 0xc, 0xb, 0x9, 0x3, 0x7, 0xe, 0x3, 0xa, 0xa, 0x0 0 0x5, 0x6, 0x0, 0xd }, {0xf, 0x3, 0x1, 0xd, 0x8, 0x4, 0xe, 0x7, 0x6, 0xf, 0xb, 0x2, 0x3, 0x8, 0x4, 0xf, 0x9, 0xc, 0x7, 0x0x1, 0xd, 0xa, 0xc, 0x6, 0x0 0x9, 0x5, 0xb, 0xa, 0x5, 0x0, 0xd, 0xe, 0x8, 0x7, 0xa, 0xb, 0x1, 0xa, 0x3, 0x4, 0xf, 0xd, 0x5, 0xb, 0x6, 0xc, 0x6, 0xc, 0x9, 0x0 0x3, 0x5, 0x2, 0xe, 0xf, 0x9}, {0xa, 0xd, 0x0 0x7, 0x9, 0x0, 0xe, 0x9, 0x6, 0x3, 0x4, 0xf, 0x6, 0x5, 0xa, 0x1, 0x2, 0xd, 0x8, 0xc, 0x5, 0x7, 0xe, 0xb, 0xc, 0x4, 0xb, 0x2, 0xf, 0x8, 0x1, 0xd, 0x1, 0x6, 0xa, 0x4, 0xd, 0x9, 0x0 0x8, 0x6, 0xf, 0x9, 0x3, 0x8, 0x0 0x7, 0xb, 0x4, 0x1, 0xf, 0x2, 0xe, 0xc, 0x3, 0x5, 0xb, 0xa, 0x5, 0xe, 0x2, 0x7, 0xc}, {0x7, 0xd, 0xd, 0x8, 0xe, 0xb, 0x3, 0x5, 0x0x6, 0x6, 0xf, 0x9, 0x0, 0xa, 0x5, 0xc, 0xb, 0x1, 0xc, 0xa, 0x4, 0xe, 0xf, 0x9, 0xa, 0x3, 0x6, 0xf, 0x9, 0x0 0x0, 0x6, 0xc, 0xa, 0xb, 0xa, 0x7, 0xd, 0xd, 0x8, 0xf, 0x9, 0x1, 0x4, 0x3, 0x5, 0xe, 0xb, 0x5, 0xc, 0x4, 0xe}, {0x2, 0xe, 0xc, 0xb, 0x1, 0xc, 0x7, 0x4, 0xa, 0x7, 0xb, 0xd, 0x6, 0x1, 0x8, 0x5, 0x5, 0 0 0x3, 0xf, 0xf, 0xa, 0xd, 0x3, 0x9, 0xe, 0x8, 0x9, 0x6, 0x4, 0xb, 0x8, 0x1, 0xc, 0xb, 0x7, 0xa, 0x1, 0xd, 0xe, 0x7, 0x2, 0x8, 0xd, 0xf, 0x6, 0x9, 0xf, 0xc, 0x0, 0x5, 0x9, 0x6, 0 XA, 0x3, 0x4, 0x0x5, 0xe, 0x3}, {0xc, 0xa, 0x1, 0xf, 0xa, 0x4, 0xf, 0x2, 0x9, 0x7, 0x2, 0xc, 0x6, 0x9, 0x8, 0x5, 0x0x6, 0xd, 0x1, 0x3, 0xd, 0x4, 0xe, 0xe, 0x0, 0x7, 0xb, 0x5, 0x3, 0xb, 0x8, 0x9, 0x4, 0xe, 0x3, 0xf, 0x2, 0x5, 0xc, 0x2, 0x9, 0x8, 0x5, 0xc, 0xf, 0x3, 0xa, 0x7, 0xb, 0x0, 0xe, 0x1, 0xa, 0 x, 0x6, 0xd, 0x0, 0xb, 0x8, 0x6, 0xd}, {0x4, 0xd, 0xb, 0x0 0x2, 0xb, 0xe, 0x7, 0xf, 0x4, 0x0 0x9, 0x8, 0x1, 0xd, 0xa, 0x3, 0xe, 0xc, 0x3, 0x9, 0x5, 0x7, 0xc, 0x5, 0x2, 0xa, 0xf, 0x6, 0x8, 0x1, 0x6, 0x6, 0x4, 0xb, 0xb, 0xd, 0xd, 0x8, 0xc, 0x1, 0x3, 0x4, 0x7, 0xa, 0xe, 0x7, 0xa, 0x9, 0xf, 0x5, 0x6, 0x0x8, 0xf, 0x0, 0xe, 0x5, 0x2, 0x9, 0x3, 0x2, 0xc}, {0xd, 0x2, 0xf, 0x8, 0xd, 0x6, 0xa, 0xf, 0x3, 0xb, 0x4, 0xa, 0xc, 0x9, 0x5, 0x3, 0x6, 0xe, 0xb, 0x5, 0x0, 0x0, 0xe, 0xc, 0x9, 0x7, 0x2, 0x7, 0x2, 0 x, 0x1, 0x4, 0xe, 0x1, 0x7, 0x9, 0x4, 0xc, 0xa, 0xe, 0x8, 0x2, 0xd, 0x0, 0xf, 0x6, 0xc, 0xa, 0x9, 0xd, 0x0, 0xf, 0x3, 0x3, 0x5, 0x5, 0x6, 0x8, 0xb }};

/* Function implementation */

Int32 ddesn (ulong8 * data, ulong8 ** key, ulong32 n_key, ulong32 readlen) {int32 I; for (I = n_key; I> 0; I --) {DDEs (data, key [I-1], readlen);} return success;} int32 desn (ulong8 * data, ulong8 ** key, ulong32 n_key, ulong32 readlen) {ulong32 I = 0; for (I = 0; I <n_key; I ++) {des (data, key [I], readlen);} return success;} int32 des3 (ulong8 * data, ulong8 * Key, ulong32 N, ulong32 readlen) {ulong32 I = 0, j = 0; makefirstkey (ulong32 *) Key ); /* generate key */for (I = 0; I <n; I ++) {for (j = 0; j <readlen; j ++ = 8) {handle_data (ulong32 *) & Data [J], desencry) ;}} return success;} int32 ddes3 (ulong8 * data, ulong8 * Key, ulong32 N, ulong32 readlen) {ulong32 I = 0, j = 0; makefirstkey (ulong32 *) Key);/* generate key */for (I = 0; I <n; I ++) {for (j = 0; j <readlen; j + = 8) {handle_data (ulong32 *) & Data [J], desdecry) ;}} return success ;} int32 des (ulong8 * data, ulong8 * Key, int32 readlen) {int32 I = 0; makefirstkey (ulong32 *) Key ); /* generate key */for (I = 0; I <readlen; I ++ = 8) {handle_data (ulong32 *) & Data [I], desencry );} return success;} int32 DDEs (ulong8 * data, ulong8 * Key, int32 readlen) {int32 I = 0; makefirstkey (ulong32 *) Key); for (I = 0; I <readlen; I + = 8) {handle_data (ulong32 *) & Data [I], desdecry);} return success;} int32 handle_data (ulong32 * left, ulong8 choice) {int32 number = 0, j = 0; ulong32 * Right = & left [1]; ulong32 TMP = 0; ulong32 tmpbuf [2] = {0 }; /* adjust wz_pc1 [64] */For (j = 0; j <64; j ++) {If (j <32) {If (wz_pc1 [J]> 32)/* belongs to right */{If (* Right & wz_pc2 [wz_pc1 [J]-1]) {tmpbuf [0] | = wz_pc2 [J] ;}} else {If (* left & wz_pc2 [wz_pc1 [J]-1]) {tmpbuf [0] | = wz_pc2 [J] ;}} else {If (wz_pc1 [J]> 32) /* belongs to right */{If (* Right & wz_pc2 [wz_pc1 [J]-1]) {tmpbuf [1] | = wz_pc2 [J];} else {If (* left & wz_pc2 [wz_pc1 [J]-1]) {tmpbuf [1] | = wz_pc2 [J] ;}} * Left = tmpbuf [0]; * Right = tmpbuf [1]; tmpbuf [0] = 0; tmpbuf [1] = 0; Switch (choice) {Case desencry: for (number = 0; number <16; number ++) {makedata (left, right, (ulong32) Number) ;}break; Case desdecry: For (number = 15; number> = 0; number --) {makedata (left, right, (ulong32) number);} break; default: break ;} /* The left and right values of the last operation are not exchanged */tmp = * left; * Left = * right; * Right = TMP; /* the last adjustment wz_pc4 [64] */For (j = 0; j <64; j ++) {If (j <32) {If (wz_pc4 [J]> 32)/* belongs to right */{If (* Right & wz_pc2 [wz_pc4 [J]-1]) {tmpbuf [0] | = wz_pc2 [J] ;}} else {If (* left & wz_pc2 [wz_pc4 [J]-1]) {tmpbuf [0] | = wz_pc2 [J] ;}} else {If (wz_pc4 [J]> 32) /* belongs to right */{If (* Right & wz_pc2 [wz_pc4 [J]-1]) {tmpbuf [1] | = wz_pc2 [J];} else {If (* left & wz_pc2 [wz_pc4 [J]-1]) {tmpbuf [1] | = wz_pc2 [J] ;}} * Left = tmpbuf [0]; * Right = tmpbuf [1]; return success;} int32 makedata (ulong32 * left, ulong32 * right, ulong32 number) {int32 J; ulong32 oldright = * right; ulong8 rexpbuf [8] = {0}; ulong32 datatmp = 0; ulong32 exp [2] = {0 }; // expanded from 32 to 48-bit for (j = 0; j <48; j ++) {/* Two 32-bit, every 24-bit */If (j <24) {If (* Right & wz_pc2 [exptab3 [J]-1]) {exp [0] | = wz_pc2 [J] ;}} else {If (* Right & wz_pc2 [exptab3 [J]-1]) {exp [1] | = wz_pc2 [j-24] ;}}for (j = 0; j <2; j ++) {exp [J] ^ = g_outkey [number] [J];}/* from 48-> 32 */exp [1]> = 8; rexpbuf [7] = (ulong8) (exp [1] & 0x0000003fl); exp [1] >>= 6; rexpbuf [6] = (ulong8) (exp [1] & 0x0000003fl); exp [1]> = 6; rexpbuf [5] = (ulong8) (exp [1] & 0x0000003fl ); exp [1] >>= 6; rexpbuf [4] = (ulong8) (exp [1] & 0x0000003fl); exp [0] >>= 8; rexpbuf [3] = (ulong8) (exp [0] & 0x0000003fl); exp [0] >>= 6; rexpbuf [2] = (ulong8) (exp [0] & 0x0000003fl); exp [0] >>= 6; rexpbuf [1] = (ulong8) (exp [0] & 0x0000003fl ); exp [0]> = 6; rexpbuf [0] = (ulong8) (exp [0] & 0x0000003fl); exp [0] = 0; exp [1] = 0; /* from 48-> 32 */* Right = 0; For (j = 0; j <7; j ++) {* Right | = Sp [J] [rexpbuf [J]; * Right <= 4;} * Right | = Sp [J] [rexpbuf [J]; /* change the position again */datatmp = 0; For (j = 0; j <32; j ++) {If (* Right & wz_pc2 [wz_pc3 [J]-1]) {datatmp | = wz_pc2 [J] ;}} * Right = datatmp; /* end all operations */* Right ^ = * left; * Left = oldright; return success;} int32 makefirstkey (ulong32 * keyp) {ulong32 key [2] = {0}; ulong32 * pkey; ulong32 * pbufkey; int32 J; pbufkey = (ulong32 *) g_bufkey; pkey = (ulong32 *) Key; memset (ulong8 *) g_bufkey, 0, sizeof (g_bufkey); memcpy (ulong8 *) & Key, (ulong8 *) keyp, 8); memset (ulong8 *) g_outkey, 0, sizeof (g_outkey); For (j = 0; j <28; j ++) {If (wz_keyleft [J]> 32) {If (pkey [1] & wz_pc2 [wz_keyleft [J]-1]) {pbufkey [0] | = wz_pc2 [J];} else {If (pkey [0] & wz_pc2 [wz_keyleft [J]-1]) {pbufkey [0] | = wz_pc2 [J];} if (wz_keyright [J]> 32) {If (pkey [1] & wz_pc2 [wz_keyright [J]-1]) {pbufkey [1] | = wz_pc2 [J] ;}} else {If (pkey [0] & wz_pc2 [wz_keyright [J]-1]) {pbufkey [1] | = wz_pc2 [J] ;}}for (j = 0; j <16; j ++) {makekey (& pbufkey [0], & pbufkey [1], J);} return success;} int32 makekey (ulong32 * keyleft, ulong32 * keyright, ulong32 number)/* enter the Key address, A 32-bit */{ulong32 tmpkey [2] = {0}; ulong32 * ptmpkey = (ulong32 *) tmpkey; ulong32 * poutkey = (ulong32 *) & g_outkey [number]; int32 J; memset (ulong8 *) tmpkey, 0, sizeof (tmpkey )); /* the highest one or two */* ptmpkey = * keyleft & wz_leftandtab [wz_lefttable [number]; ptmpkey [1] = * keyright & wz_leftandtab [wz_lefttable [number]; If (wz_lefttable [number] = 1) {* ptmpkey >>=27; ptmpkey [1] >>=27;} else {* ptmpkey >>=26; ptmpkey [1] >>=26;} ptmpkey [0] & = 0xfffffff0; ptmpkey [1] & = 0xfffffff0;/* Get the high value */* keyleft <= wz_lefttable [number]; * keyright <= wz_lefttable [number]; * keyleft | = ptmpkey [0]; * keyright | = ptmpkey [1]; ptmpkey [0] = 0; ptmpkey [1] = 0; /* select 48 digits from 56 digits, 3 16 digits */For (j = 0; j <48; j ++) {If (j <24) {If (* keyleft & wz_pc2 [wz_keychoose [J]-1]) {poutkey [0] | = wz_pc2 [J];} else/* j> = 24 */{If (* keyright & wz_pc2 [(wz_keychoose [J]-28)]) {poutkey [1] | = wz_pc2 [j-24] ;}}return success ;}

The code is tested in the Win2000/vc6.0 environment.

Author information:
Address: Xi'an Datang Telecom Data Communication Department, No. 8 Changhui South Road, Xi'an (710075, China)
Tel: 029-8379381
E-mail: hitwz@163.com

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.