DES算法笔记

DES简介

发布文档:FIPS 46-3, 1977

  • block size: 8 bytes.
  • Key Size: 8 bytes == 64 bits, 原本设计每隔7 bits保留一个校验位 (bit 8, 16, 64, 确保每个字节里有奇数个1),所以实际为56 bits,但校验位实际并没有用到。
  • Feistel structure

DES算法没有被攻破,只是密钥太短,发布多年后已经很容易被暴力破解。

Feistel

DES的结构由Horst Feistel设计,因此也被称为Feistel network/structure/cipher,该结构也应用于很多其它密码算法。

特点:

  • 轮数可以任意增加
  • 轮函数f同时用于加解密
  • 加解密都使用该结构,解密时只需要逆序使用子密钥
  • 16 轮(round)运算

DES算法流程

请添加图片描述

Enciphering

第一步是Initial Permutation初始置换(简称IP)

初始置换,根据下面的bit索引重新排序,将输入分成左右(L, R)各32 bits。

/* Initial Permutation Table 
* 64 bits --> 32 bit L + 32 bit R
*/
static const uint8_t IP[] = {
    // L
	58, 50, 42, 34, 26, 18, 10,  2,
	60, 52, 44, 36, 28, 20, 12,  4,
	62, 54, 46, 38, 30, 22, 14,  6,
	64, 56, 48, 40, 32, 24, 16,  8,
    // R
	57, 49, 41, 33, 25, 17,  9,  1,
	59, 51, 43, 35, 27, 19, 11,  3,
	61, 53, 45, 37, 29, 21, 13,  5,
	63, 55, 47, 39, 31, 23, 15,  7
};

之后进行16轮运算:

L' = R
R' = L ^ f(R, K)

Key Schedule

KS流程位于FIPS 46-3 附录1。

在轮运算中,用到了一个f函数,其中,48 bit长的子密钥参数K是依据key schedule function (KS)从子密钥中选择的:

K = KS(n, KEY)
n in [1, ..., 16]

KS也是16轮函数,每轮生成Feistel中对应的子密钥。

KS有两个置换选择矩阵(Permuted choice):

/*
* Permuted choice
* 64 bits --> 28 bits + 28 bits
*/
static const uint8_t pc1[56] = {
    // C
	57, 49,  41, 33,  25,  17,  9,
	 1, 58,  50, 42,  34,  26, 18,
	10,  2,  59, 51,  43,  35, 27,
	19, 11,   3, 60,  52,  44, 36,
    // D
	63, 55,  47, 39,  31,  23, 15,
	 7, 62,  54, 46,  38,  30, 22,
	14,  6,  61, 53,  45,  37, 29,
	21, 13,   5, 28,  20,  12,  4
};



/*
* Permuted choice 2
*	56 bits --> 48 bits subkey
*/
static const unsigned char pc2[48] = {
	14, 17, 11, 24,  1,  5,
	 3, 28, 15,  6, 21, 10,
	23, 19, 12,  4, 26,  8,
	16,  7, 27, 20, 13,  2,
	41, 52, 31, 37, 47, 55,
	30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53,
	46, 42, 50, 36, 29, 32
};


static const unsigned char LeftShifts[16] = {
	1, 1, 2, 2,
	2, 2, 2, 2,
	1, 2, 2, 2,
	2, 2, 2, 1
};

PC1将原始64 bits Key过滤掉8个检验位,并分为C、D两个28 bits,通过将C、D左移并由PC2置换后得到轮函数的48 bit K参数。

以C2 D2为例

C2D2 = (C1 << 1) || (D1 << 1)
K1 = PC2(C1D1)

Deciphering

与加密一样,再走一遍Fetstel结构,但需要将子密钥逆序使用。

最后一步,针对IP进行逆置换(inverse of IP,IP-1),将第16轮的输出进行合并。

/* Inverse Initial Permutation Table */
static const uint8_t InverseIP[64] = {
	40,  8, 48, 16, 56, 24, 64, 32,
	39,  7, 47, 15, 55, 23, 63, 31,
	38,  6, 46, 14, 54, 22, 62, 30,
	37,  5, 45, 13, 53, 21, 61, 29,
	36,  4, 44, 12, 52, 20, 60, 28,
	35,  3, 43, 11, 51, 19, 59, 27,
	34,  2, 42, 10, 50, 18, 58, 26,
	33,  1, 41,  9, 49, 17, 57, 25
};

The Cipher Function f(R, K)

f(32 bit R, 48 bit K)

轮函数f组成如下:

  • Extend function E(32 bits)->48 bits;
  • 8 selection functions Sn(6 bits)–>4 bits;
  • Permutation function P(32 bits)–>32 bits

请添加图片描述

E扩展函数其实就是把输入的32 bits按如下下标重新排列为48 bits:

/*	Extend table for f(R, k)
*/
static const uint8_t E[] = {
	32,  1,  2,  3,  4,  5,
	 4,  5,  6,  7,  8,  9,
	 8,  9, 10, 11, 12, 13,
	12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21,
	20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29,
	28, 29, 30, 31, 32,  1
};

选择函数,以S1表为例

0123456789101112131415
01441312151183106125907
10157414213110612119538
24114813621115129731050
31512824917511314100613

比如,输入 011011 ,则取首尾比特01(1)为行,中间4比特1101(13)为列,输出为5(0101)。

其它S表位于FIPS 46-3 附录。有些资料也把它称作S-box。

P置换函数,与扩展函数类似,将输入重新排序:

static const uint8_t P[32] = {
	16,  7, 20, 21,
	29, 12, 28, 17,
	 1, 15, 23, 26,
	 5, 18, 31, 10,
	 2,  8, 24, 14,
	32, 27,  3,  9,
	19, 13, 30,  6,
	22, 11,  4, 25
};

Triple DES算法

Triple DES (or TDES or TDEA or 3DES) ,

发布文档: SP 800-67 Rev1。

  • 1999年,NIST将3-DES指定为过渡的加密标准。
  • 3DES是将明文进行3次DES来加密。
  • 采用IBM设计的EDE流程(Encryption - Decryption - Encryption)
  • 需要3个DES密钥k1, k2, k3。
    • 如果3个密钥都相同,则等价于DES;
    • 如果k1 == k3 != k2,则称为EDE2,密钥长16 字节,但安全等级为90 bits;
    • 如果3个密钥都不同,则称为EDE3,密钥长24字节,安全等级112 bits。

安全等级的取值,参考了A Known-Plaintext Attack on Two-Key Triple Encryption这篇文章。

OpenSSL接口

旧接口
https://www.openssl.org/docs/man3.0/man3/DES_ecb_encrypt.html
EVP接口
https://www.openssl.org/docs/man3.0/man3/EVP_EncryptInit.html
https://www.openssl.org/docs/man3.0/man3/EVP_des_cbc.html

S-box

/* The S-Box tables */
static const uint8_t S[8][64] = { 
    {
		/* S1 */
		14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
		 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
		 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
		15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13
	},{
		/* S2 */
		15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
		 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
		 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
		13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9
	},{
		/* S3 */
		10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
		13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
		13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
		 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12
	},{
		/* S4 */
		 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
		13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
		10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
		 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14
	},{
		/* S5 */
		 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
		14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
		 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
		11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3
	},{
		/* S6 */
		12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
		10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
		 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
		 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13
	},{
		/* S7 */
		 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
		13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
		 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
		 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12
	},{
		/* S8 */
		13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
		 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
		 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
		 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
	} 
};

实现

https://github.com/C0deStarr/CryptoImp/tree/main/Cipher/BlockCipher

  • des.h
  • des.c
  • des3.h
  • des3.c

参考资料

FIPS 46-3, Data Encryption Standard (DES) | CSRC (nist.gov)

SP 800-67 Rev. 2, Recommendation for the TDEA Block Cipher | CSRC (nist.gov)

A Known-Plaintext Attack on Two-Key Triple Encryption

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值