OpenSSL DES DES_set_key_unchecked函数分析

void DES_set_key_unchecked( const DES_cblock * key, DES_key_schedule * schedule )

 输入参数:

key,指向原始密钥的指针,原始密钥共有8字节

schedule,指向存放16个子密钥的指针,每个密钥占用8个字节

k = &schedule->ks->deslong[0] ; 

k为unsigned long类型指针,此时k指向存放子密钥的开始处

in = &( * key )[0];

in为unsigned char类型指针,此时in指向原始密钥的开始处

c2l( in, c ) ;

从原始密钥中取出前4个字节,如表1所示

c2l( in, d ) ;

从原始密钥中取出后4个字节,如表2所示

表1 c

25

26

27

28

29

30

31

32

17

18

19

20

21

22

23

24

9

10

11

12

13

14

15

16

1

2

3

4

5

6

7

8


表2 d

57

58

59

60

61

62

63

64

49

50

51

52

53

54

55

56

41

42

43

44

45

46

47

48

33

34

35

36

37

38

39

40

 PERM_OP( d, c, t, 4, 0x0f0f0f0fL ) ;

将d的前4列与c的后4列交换,交换结果如表3和表4所示

表3 c

25

26

27

28

57

58

59

60

17

18

19

20

49

50

51

52

9

10

11

12

41

42

43

44

1

2

3

4

33

34

35

36


表4 d

29

30

31

32

61

62

63

64

21

22

23

24

53

54

55

56

13

14

15

16

45

46

47

48

5

6

7

8

37

38

39

40

HPERM_OP( c, t, -2, 0xcccc0000L ) ;

将c变量进行交换,结果如表5所示

表5 c

11

12

27

28

43

44

59

60

3

4

19

20

35

36

51

52

9

10

25

26

41

42

57

58

1

2

17

18

33

34

49

50

 HPERM_OP( d, t, -2, 0xcccc0000L ) ;

将d变量进行交换,结果如表6所示

表6 d

15

16

31

32

47

48

63

64

7

8

23

24

39

40

55

56

13

14

29

30

45

46

61

62

5

6

21

22

37

38

53

54

 PERM_OP( d, c, t, 1, 0x55555555L ) ;

将变量d的前1列与变量c的后1列交换,如表7和8所示

表7 c

11

15

27

31

43

47

59

63

3

7

19

23

35

39

51

55

9

13

25

29

41

45

57

61

1

5

17

21

33

37

49

53


表8 d

12

16

28

32

44

48

60

64

4

8

20

24

36

40

52

56

10

14

26

30

42

46

58

62

2

6

18

22

34

38

50

54

PERM_OP( c, d, t, 8, 0x00ff00ffL ) ;

将变量c的前8列与变量d的后8列交换,如表9和10所示

表9 c

4

8

20

24

36

40

52

56

3

7

19

23

35

39

51

55

2

6

18

22

34

38

50

54

1

5

17

21

33

37

49

53

 

表10 d

12

16

28

32

44

48

60

64

11

15

27

31

43

47

59

63

10

14

26

30

42

46

58

62

9

13

25

29

41

45

57

61

 PERM_OP( d, c, t, 1, 0x55555555L ) ;

将变量d的前1列与变量c的后1列交换,如表11和12所示

表11 c

4

12

20

28

36

44

52

60

3

11

19

27

35

43

51

59

2

10

18

26

34

42

50

58

1

9

17

25

33

41

49

57


表12 d

8

16

24

32

40

48

56

64

7

15

23

31

39

47

55

63

6

14

22

30

38

46

54

62

5

13

21

29

37

45

53

61

 经过以上一系列位组交换和移动后,已经将奇偶校验位调整到变量d的前8位中。

 d = ( ( ( d & 0x000000ffL ) << 16L ) | ( d & 0x0000ff00L ) |

        ( ( d & 0x00ff0000L ) >> 16L ) | ( ( c & 0xf0000000L ) >> 4L ) ) ;

调整变量d的字节顺序,并将变量c的前4位调整到变量d中,如表13所示,发现与标准中的D0位序是相反的,即到序

表13 d

 

 

 

 

4

12

20

28

5

13

21

29

37

45

53

61

6

14

22

30

38

46

54

62

7

15

23

31

39

47

55

63

 c &= 0x0fffffffL ;

去掉变量c的前4位,如表14所示,发现与标准中的C0位序是相反的,即到序 

表14 c

 

 

 

 

36

44

52

60

3

11

19

27

35

43

51

59

2

10

18

26

34

42

50

58

1

9

17

25

33

41

49

57

 到此为止同时完成了去掉校验位(8位)和PC-1(8x7)置换。

 for( i = 0 ; i < ITERATIONS ; i++ )

迭代16次,ITERATIONS = 16

c = ( ( c >> 1L ) | ( c << 27L ) ) ;

d = ( ( d >> 1L ) | ( d << 27L ) ) ;

因为C0和D0与标准中的位序相反,所以循环移位也是相反的

首次循环移位后的结果如表15和表16所示

表15 c

 

 

 

 

57

36

44

52

60

3

11

19

27

35

43

51

59

2

10

18

26

34

42

50

58

1

9

17

25

33

41

49

 

表16 d

 

 

 

 

63

4

12

20

28

5

13

21

29

37

45

53

61

6

14

22

30

38

46

54

62

7

15

23

31

39

47

55

 s = des_skb[ 0 ][ ( c ) & 0x3f ] |                                                                                                         (注1)

      des_skb[ 1 ][ ( ( c >> 6L ) & 0x03 ) | ( ( c >> 7L ) & 0x3c ) ] |                                                       (注2)

      des_skb[ 2 ][ ( ( c >> 13L ) & 0x0f ) | ( ( c >> 14L ) & 0x30 ) ] |                                                   (注3)

      des_skb[ 3 ][ ( ( c >> 20L ) & 0x01 ) | ( ( c >> 21L ) & 0x06 )  | ( ( c >> 22L ) & 0x38 ) ] ;           (注4)

取出4组6位组查表des_skb,并将查表数值进行或组合

 注1

(A)( c ) & 0x3f,为[9][17][25][33][41][49],共6位;

(B)C位组:[1][2][3][4][5][6]对应des_skb表中数据的位置

 注2

(A)( ( c >> 6L ) & 0x03 ),为[58][1],共2位;

(B)( ( c >> 7L ) & 0x3c ),为[18][26][34][42],共4位

(C)[18][26][34][42][58][1],共6位;

 注3

(A)( ( c >> 13L ) & 0x0f ),为[51][59][2][10],共4位;

(B)( ( c >> 14L ) & 0x30 ),为[27][35],共2位;

(C)[27][35][51][59][2][10],共6位;

 注4

(A)( ( c >> 20L ) & 0x01 ),为[19],共1位;

(B)( ( c >> 21L ) & 0x06 ),为[60][3],共2位;

(C)( ( c >> 22L ) & 0x38 ),为[57][36][44],共3位;

(D)[57][36][44][60][3][19],共6位;

 按照标准丢弃第9,18,22和25位,因为是倒序,所以丢弃的为[50][43][11][52],共4位,如表17所示;

表17 丢弃位所在位置

 

 

 

 

57

36

44

52

60

3

11

19

27

35

43

51

59

2

10

18

26

34

42

50

58

1

9

17

25

33

41

49

 t = des_skb[ 4 ][ ( d ) & 0x3f ] |                                                                         (注5)

     des_skb[ 5 ][ ( ( d >> 7L ) & 0x03 ) | ( ( d >> 8L ) & 0x3c ) ] |                      (注6)

     des_skb[ 6 ][ ( d >> 15L ) & 0x3f ] |                                                             (注7)

     des_skb[ 7 ][ ( ( d >> 21L ) & 0x0f ) | ( ( d >> 22L ) & 0x30 ) ] ;                  (注8)

取出4组6位组查表des_skb,并将查表数值进行或组合

 注5

(A)( d ) & 0x3f,为[15][23][31][39][47][55],共6位;

 注6

(A)( ( d >> 7L ) & 0x03 ),为[54][61],共2位;

(B)( ( d >> 8L ) & 0x3c ),为[14][22][30][38],共4位;

(C)[14][22][30][38][54][61],共6位;

注7

(A)( d >> 15L ) & 0x3f,为[21][29][37][45][53][61],共6位;

注8

(A)( ( d >> 21L ) & 0x0f ),为[20][28][5][13],共4位;

(B)( ( d >> 22L ) & 0x30 ),为[63][4],共2位;

(C)[63][4][20][28][5][13],共6位

按照标准丢弃第35,38,43和54位,因为是倒序,所以丢弃的为[7][46][6][12],共4位,如表18所示;

对于d来说丢弃的是第7,10,15和26位。

表18 丢弃位所在位置

 

 

 

 

63

4

12

20

28

5

13

21

29

37

45

53

61

6

14

22

30

38

46

54

62

7

15

23

31

39

47

55

 C位组在des_skb数据中的数据,如表19~22所示。

表19

6

5

4

3

2

1

des_skb

倒序位数

0

0

0

0

0

1

0000-0010

5

0

0

0

0

1

0

2000-0000

30

0

0

0

1

0

0

0001-0000

17

0

0

1

0

0

0

0000-0800

12

0

1

0

0

0

0

0000-0020

6

1

0

0

0

0

0

0008-0000

20

 

 

 

 

 

 

2009-0830

 


表20

13

12

11

10

8

7

des_skb

倒序位数

0

0

0

0

0

1

0200-0000

26

0

0

0

0

1

0

0000-2000

14

0

0

0

1

0

0

0020-0000

22

0

0

1

0

0

0

0000-0004

3

0

1

0

0

0

0

0000-0400

11

1

0

0

0

0

0

1000-0000

29

 

 

 

 

 

 

1220-2404

 

 

表21

20

19

17

16

15

14

des_skb

倒序位数

0

0

0

0

0

1

0000-0001

1

0

0

0

0

1

0

0004-0000

19

0

0

0

1

0

0

0100-0000

25

0

0

1

0

0

0

0000-0002

2

0

1

0

0

0

0

0000-0200

10

1

0

0

0

0

0

0800-0000

28

 

 

 

 

 

 

0904-0203

 


表22

29

27

26

24

23

21

des_skb

倒序位数

0

0

0

0

0

1

0010-0000

21

0

0

0

0

1

0

0000-0100

9

0

0

0

1

0

0

0000-0008

4

0

0

1

0

0

0

0000-1000

13

0

1

0

0

0

0

0400-0000

27

1

0

0

0

0

0

0002-0000

18

 

 

 

 

 

 

0412-1108

 

由表19~22可知C位组在des_skb中占用的位,2009-0830 | 1220-2404 | 0904-0203 | 0412-1108  = 3F3F-3F3F;

    倒序:第1-6位,第  9-14位,第17-22位,第25-30位,共24位。

 

表23 C位组原始排序

6

5

4

3

2

1

13

12

11

10

8

7

20

19

17

16

15

14

28

27

26

24

23

21

 

表24 C位组置换表

20

6

12

17

30

5

29

11

3

22

14

26

28

10

2

25

19

1

18

27

13

4

9

21

 

 

 

表25 C位组经过置换后的排序

字节序号

位序号

8

7

6

5

4

3

2

1

3

32~25

 

 

2

13

20

27

7

16

1

24~17

 

 

10

21

6

15

28

3

2

16~9

 

 

8

26

4

12

19

23

0

8~1

 

 

5

1

24

11

17

14

 注意:表中s的数值排序与标准中的排序不同。

 D位组在des_skb数据中的数据,如表26~29所示。

表26

6

5

4

3

2

1

des_skb

倒序位数

0

0

0

0

0

1

1000-0000

29

0

0

0

0

1

0

0001-0000

17

0

0

0

1

0

0

0000-0004

3

0

0

1

0

0

0

2000-0000

30

0

1

0

0

0

0

0010-0000

21

1

0

0

0

0

0

0000-1000

13

 

 

 

 

 

 

3011-1004

 


表27

14

13

12

11

9

8

des_skb

倒序位数

0

0

0

0

0

1

0800-0000

28

0

0

0

0

1

0

0000-0008

4

0

0

0

1

0

0

0000-0400

11

0

0

1

0

0

0

0002-0000

18

0

1

0

0

0

0

0000-0001

1

1

0

0

0

0

0

0200-0000

26

 

 

 

 

 

 

0A02-0409

 


表28

21

20

19

18

17

16

des_skb

倒序位数

0

0

0

0

0

1

0000-0100

9

0

0

0

0

1

0

0008-0000

20

0

0

0

1

0

0

0100-0000

25

0

0

1

0

0

0

0000-0010

5

0

1

0

0

0

0

0020-0000

22

1

0

0

0

0

0

0000-0200

10

 

 

 

 

 

 

0128-0310

 


表29

28

27

25

24

23

22

des_skb

倒序位数

0

0

0

0

0

1

0400-0000

27

0

0

0

0

1

0

0004-0000

19

0

0

0

1

0

0

0000-0002

2

0

0

1

0

0

0

0000-2000

14

0

1

0

0

0

0

0000-0020

6

1

0

0

0

0

0

0000-0800

12

 

 

 

 

 

 

0404-2822

 

    由表26~29可知D位组在des_skb中占用的位,3011-1004 | 0A02-0409 | 0128-0310 | 0404-2822  = 3F3F-3F3F;

    倒序:第1-6位,第  9-14位,第17-22位,第25-30位,共24位。

表30 D位组原始排序

6

5

4

3

2

1

14

13

12

11

9

8

21

20

19

18

17

16

28

27

25

24

23

22


表31 D位组置换表

13

21

30

3

17

29

26

1

18

11

4

28

10

22

5

25

20

9

12

6

14

2

19

27


 

 

表32 D位组经过置换后的排序

字节序号

位序号

8

7

6

5

4

3

2

1

7

32~25

 

 

4

1

8

22

14

18

5

24~17

 

 

20

5

17

23

12

2

6

16~9

 

 

25

6

28

11

21

16

4

8~1

 

 

27

19

9

3

24

13


 

 

表32’ D位组(D位组位序号增加28)经过置换后的排序

字节序号

位序号

8

7

6

5

4

3

2

1

7

32~25

 

 

32

29

36

50

42

46

5

24~17

 

 

48

33

45

51

40

30

6

16~9

 

 

53

34

56

39

49

44

4

8~1

 

 

55

47

37

31

52

41

注意:表中t的数值排序与标准中的排序不同。

t2 = ( ( t << 16L ) | ( s & 0x0000ffffL ) ) & 0xffffffffL ;                                       (注9)

*( k++ ) = ROTATE( t2, 30 ) & 0xffffffffL ;                                                       (注10) 

t2 = ( ( s >> 16L ) | ( t & 0xffff0000L ) ) ;                                                        (注11)

*( k++ ) = ROTATE( t2, 26 ) & 0xffffffffL ;                                                       (注12)

 注9

表33

t

6

 

 

53

34

56

39

49

44

4

 

 

55

47

37

31

52

41

s

2

 

 

8

26

4

12

19

23

0

 

 

5

1

24

11

17

14

 注10 保存在子密钥缓冲区中的子密钥格式,共24位,靠左侧放置。

表34

t

6

53

34

56

39

49

44

 

 

4

55

47

37

31

52

41

 

 

s

2

8

26

4

12

19

23

 

 

0

5

1

24

11

17

14

 

 

 注11

表35

t

7

 

 

32

29

36

50

42

46

5

 

 

48

33

45

51

40

30

s

3

 

 

2

13

20

27

7

16

1

 

 

10

21

6

15

28

3

 注12 保存在子密钥缓冲区中的子密钥格式,共24位,右循环移动4位后与表34格式相同。

表36

t

7

42

46

 

 

2

13

20

27

5

40

30

 

 

10

21

6

15

s

3

7

16

 

 

32

29

36

50

1

28

3

 

 

48

33

45

51


<think>好的,我需要帮助用户找到使用C语言调用OpenSSL实现DES加密的代码示例。首先,我需要回忆OpenSSL库中DES加密相关的函数和结构。记得OpenSSLDES加密主要有ECB和CBC模式,用户可能需要这两种模式的示例。 接下来,我应该检查用户提供的引用内容。引用[3]提到了DES_ecb_encrypt函数,引用[5]提到了DES_ncbc_encrypt,但用户的问题是关于DES_encrypt的示例。不过DES_encrypt可能已经过时,现在推荐使用更安全的函数,比如DES_ecb_encrypt或DES_ncbc_encrypt,并正确设置密钥结构。 我需要确保代码示例的正确性,包括密钥设置、数据填充等。例如,在ECB模式下,数据需要是8字节的倍数,否则需要填充。同时,要处理可能的段错误,如引用[5]中提到的,可能需要正确初始化内存。 然后,我需要编写两个示例,一个ECB模式,一个CBC模式,展示如何设置密钥、加密数据,并处理输入输出。同时,提醒用户注意编译时链接OpenSSL库,比如使用-lcrypto参数。 最后,生成相关问题,涵盖其他加密算法、模式选择、填充处理等,帮助用户扩展知识。确保所有步骤符合系统级指令,如使用正确的LaTeX格式,添加引用标识,并保持回答结构清晰。</think>以下是使用C语言调用OpenSSL实现DES加密的两种典型模式(ECB/CBC)的代码示例: ### 一、DES-ECB模式加密示例 ```c #include <openssl/des.h> #include <string.h> int des_ecb_encrypt(const unsigned char *plain, int plain_len, unsigned char *cipher, DES_key_schedule *ks) { if (plain_len % 8 != 0) return -1; // 需要8字节对齐 for(int i=0; i<plain_len; i+=8) { DES_ecb_encrypt(plain + i, cipher + i, ks, DES_ENCRYPT); } return 0; } int main() { DES_cblock key = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; DES_key_schedule key_schedule; DES_set_key_unchecked(&key, &key_schedule); // 密钥设置[^3] unsigned char plaintext[8] = "12345678"; unsigned char ciphertext[8]; des_ecb_encrypt(plaintext, 8, ciphertext, &key_schedule); return 0; } ``` ### 二、DES-CBC模式加密示例 ```c #include <openssl/des.h> int des_cbc_encrypt(const unsigned char *plain, int plain_len, unsigned char *cipher, DES_key_schedule *ks, DES_cblock *iv) { int padding = 8 - (plain_len % 8); int new_len = plain_len + padding; unsigned char *padded = malloc(new_len); memcpy(padded, plain, plain_len); memset(padded + plain_len, padding, padding); // PKCS#5填充 DES_ncbc_encrypt(padded, cipher, new_len, ks, iv, DES_ENCRYPT); // CBC加密[^5] free(padded); return new_len; } int main() { DES_cblock key = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; DES_cblock iv = {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}; DES_key_schedule key_schedule; DES_set_key_unchecked(&key, &key_schedule); unsigned char plaintext[12] = "Hello DES!"; unsigned char ciphertext[16]; int cipher_len = des_cbc_encrypt(plaintext, 12, ciphertext, &key_schedule, &iv); return 0; } ``` **关键注意事项:** 1. 密钥必须为8字节,通过`DES_set_key_unchecked`设置密钥调度表[^4] 2. ECB模式需要明文长度是8的倍数,CBC模式需要手动添加填充(如PKCS#5) 3. 使用编译参数 `-lssl -lcrypto` 链接OpenSSL库[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值