返回
北京兄弟连IT
置顶
该校与厚学网暂未合作,平台不保证课程的真实有效性,如有侵权等争议,请及时与厚学网联系处理
招生热线:400-800-2181

学校地址:北京市昌平区回龙观文华西路育荣教育园区兄弟连IT教育

兄弟连区块链教程信息安全2DES3DES

143 2018-11-12 11:27:29

学习笔记

  兄弟连区块链教程区块链背后的信息安全2DES3DES加密算法原理一,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# DES、3DES加密算法原理及其GO语言实现

 

DES加密算法,为对称加密算法中的一种。70年代初由IBM研发,后1977年被美国标准局采纳为数据加密标准,即DES全称的由来:Data Encryption Standard。

对称加密算法,是相对于非对称加密算法而言的。两者区别在于,对称加密在加密和解密时使用同一密钥,而非对称加密在加密和解密时使用不同的密钥,即公钥和私钥。

常见的DES、3DES、AES均为对称加密算法,而RSA、椭圆曲线加密算法,均为非对称加密算法。

 

DES是以64比特的明文为一个单位来进行加密的,超过64比特的数据,要求按固定的64比特的大小分组,分组有很多模式,后续单独总结,暂时先介绍DES加密算法。

DES使用的密钥长度为64比特,但由于每隔7个比特设置一个奇偶校验位,因此其密钥长度实际为56比特。奇偶校验为zui简单的错误检测码,即根据一组二进制代码中1的个数是奇数或偶数来检测错误。

 

## Feistel网络

 

DES的基本结构,由IBM公司的Horst Feistel设计,因此称Feistel网络。

Feistel网络中,加密的每个步骤称为轮,经过初始置换后的64位明文,进行了16轮Feistel轮的加密过程,zui经过终结置换后形成zui终的64位密文。

 

64比特明文被分为左、右两部分处理,右侧数据和子密钥经过轮函数f生成用于加密左侧数据的比特序列,与左侧数据异或运算,运算结果输出为加密后的左侧,右侧数据则直接输出为右侧。

其中子密钥为本轮加密使用的密钥,每次Feistel均使用不同的子密钥。子密钥的计算,以及轮函数的细节,稍后下文介绍。

由于一次Feistel轮并不会加密右侧,因此需要将上一轮输出后的左右两侧对调后,重复Feistel轮的过程,DES算法共计进行16次Feistel轮,zui一轮输出后左右两侧无需对调。

 

DES加密和解密的过程一致,均使用Feistel网络实现,区别仅在于解密时,密文作为输入,并逆序使用子密钥。

 

go标准库中DES算法实现如下:

 

```go

func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) {

    b := binary.BigEndian.Uint64(src)

    //初始置换

    b = permuteInitialBlock(b)

    left, right := uint32(b>>32), uint32(b)

 

    var subkey uint64

    //共计16次feistel轮

    for i := 0; i < 16; i++ {

        //加密和解密使用子密钥顺序相反

        if decrypt {

            subkey = subkeys[15-i]

        } else {

            subkey = subkeys[i]

        }

        //feistel轮函数

        left, right = right, left^feistel(right, subkey)

    }

    //zui一轮无需对调

    preOutput := (uint64(right) << 32) | uint64(left)

    //终结置换

    binary.BigEndian.PutUint64(dst, permuteFinalBlock(preOutput))

}

//代码位置src/crypto/des/block.go

```

 

## 初始置换和终结置换

 

进入Feistel轮之前,64位明文需做一次初始置换。Feistel轮结束后,需做一次反向操作,即终结置换。

初始置换和终结置换目的是为加强硬件的破-解难度而加的。

 

go标准库中使用的初始置换表和终结置换表如下:

 

```go

//初始置换表

var initialPermutation = [64]byte{

    6, 14, 22, 30, 38, 46, 54, 62,

    4, 12, 20, 28, 36, 44, 52, 60,

    2, 10, 18, 26, 34, 42, 50, 58,

    0, 8, 16, 24, 32, 40, 48, 56,

    7, 15, 23, 31, 39, 47, 55, 63,

    5, 13, 21, 29, 37, 45, 53, 61,

    3, 11, 19, 27, 35, 43, 51, 59,

    1, 9, 17, 25, 33, 41, 49, 57,

}

 

//终结置换表

var finalPermutation = [64]byte{

    24, 56, 16, 48, 8, 40, 0, 32,

    25, 57, 17, 49, 9, 41, 1, 33,

    26, 58, 18, 50, 10, 42, 2, 34,

    27, 59, 19, 51, 11, 43, 3, 35,

    28, 60, 20, 52, 12, 44, 4, 36,

    29, 61, 21, 53, 13, 45, 5, 37,

    30, 62, 22, 54, 14, 46, 6, 38,

    31, 63, 23, 55, 15, 47, 7, 39,

}

//代码位置src/crypto/des/const.go

```

 

## 子密钥的计算

 

DES初始密钥为64位,其中8位用于奇偶校验,实际密钥为56位,64位初始密钥经过PC-1密钥置换后,生成56位串。

PC-1置换后56位的串,分为左右两部分,各28位,分别左移1位,形成C0和D0,C0和D0合并成56位,经PC-2置换后生成48位子密钥K0。

C0和D0分别左移1位,形成C1和D1,C1和D1合并成56位,经PC-2置换后生成子密钥K1。

以此类推,直至生成子密钥K15。但注意每轮循环左移的位数,有如下规定:

 

```go

var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}

//代码位置src/crypto/des/const.go

```

 

go标准库中DES子密钥计算的代码如下:

 

```go

func (c *desCipher) generateSubkeys(keyBytes []byte) {

    key := binary.BigEndian.Uint64(keyBytes)

    //PC-1密钥置换,生成56位串

    permutedKey := permuteBlock(key, permutedChoice1[:])

 

    //56位串分左右两部分,各28位,ksRotate为依次循环左移1位

    leftRotations := ksRotate(uint32(permutedKey >> 28))

    rightRotations := ksRotate(uint32(permutedKey<<4) >> 4)

 

    //生成子密钥

    for i := 0; i < 16; i++ {

        //合并左右两部分,之后PC-2置换

        pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i])

        c.subkeys[i] = permuteBlock(pc2Input, permutedChoice2[:])

    }

}

//代码位置src/crypto/des/block.go

```

 

go标准库中使用的PC-1置换表和PC-2置换表:

 

```go

//PC-1置换表

var permutedChoice1 = [56]byte{

    7, 15, 23, 31, 39, 47, 55, 63,

    6, 14, 22, 30, 38, 46, 54, 62,

    5, 13, 21, 29, 37, 45, 53, 61,

    4, 12, 20, 28, 1, 9, 17, 25,

    33, 41, 49, 57, 2, 10, 18, 26,

    34, 42, 50, 58, 3, 11, 19, 27,

    35, 43, 51, 59, 36, 44, 52, 60,

}

 

//PC-2置换表

var permutedChoice2 = [48]byte{

    42, 39, 45, 32, 55, 51, 53, 28,

    41, 50, 35, 46, 33, 37, 44, 52,

    30, 48, 40, 49, 29, 36, 43, 54,

    15, 4, 25, 19, 9, 1, 26, 16,

    5, 11, 23, 8, 12, 7, 17, 0,

    22, 3, 10, 14, 6, 20, 27, 24,

}

//代码位置src/crypto/des/const.go

```

 

未完待续感谢关注兄弟连区块链教程分享!

 

文中图片素材来源网络,如有侵权请联系删除
来源:北京兄弟连IT
热门课程 全部课程

热门动态

申请免费试听

只要一个电话

我们为您免费回电

立即申请
刷新
图形验证
关闭
>>
拖动左边滑块完成上方拼图