Simplified-DES的實(shí)現(xiàn)

題目描述

實(shí)驗?zāi)康?/h3>

1) 學(xué)習(xí)S-DES密碼算法的原理

2) 掌握S-DES密碼算法的實(shí)現(xiàn)

實(shí)驗原理

1) 算法原理

Simplified DES方案,簡稱S-DES方案,是DES算法的簡化版。它是一個供教學(xué)而非安全的加密算法,它與DES的特性和結(jié)構(gòu)類似,但參數(shù)小。

加密算法涉及五個函數(shù):

(1)初始置換IP(initial permutation)

(2)復(fù)合函數(shù)fk1,它是由密鑰K確定的,具有置換和代換的運(yùn)算。

(3)置換函數(shù)SW

(4)復(fù)合函數(shù)fk2

(5)初始置換IP的逆置換IP-1

[圖片上傳失敗...(image-13062e-1668674986761)]

image.png
image.png
image.png

2) 算法參數(shù)——S-DES所需的幾個置換表

① P10={3,5,2,7,4,10,1,9,8,6}

② P8={6,3,7,4,8,5,10,9} 注意這個置換選擇輸入10位輸出8位

③ P4={2,4,3,1}

④ IP={2,6,3,1,4,8,5,7}

⑤ IP-1={4,1,3,5,7,2,8,6}

⑥ EP={4,1,2,3,2,3,4,1} 注意這個是擴(kuò)展置換,輸入4位輸出8位

⑦ 兩個S盒:

S0:

{1,0,3,2}

{3,2,1,0}

{0,2,1,3}

{3,1,3,2}

S1:

{0,1,2,3}

{2,0,1,3}

{3,0,1,0}

{2,1,0,3}

3) 算法說明

若明文為: m=0001 0110, key選為(01111 11101),給出加密過程和解密過程,并計算出密文和明文。

a)子密鑰的生成

① 10位密鑰key = 01111 11101

② 對key做P10置換(P10={3,5,2,7,4,10,1,9,8,6})得到 11111 10011

③ 記左半(高位)的為Lk=11111,右半(低位)為Rk=10011

④ LS-1:Lk和Rk均循環(huán)左移1位,得到Lk=11111,Rk=00111

⑤ 對Lk和Rk組合得到的11111 00111做P8置換(P8={6,3,7,4,8,5,10,9})選擇,得到子密鑰K1=0101 1111

⑥ LS-2:Lk和Rk均再次循環(huán)左移2位,得到Lk=11111,Rk=11100

⑦ P8:對Lk和Rk組合得到的11111 11100做P8置換選擇,得到子密鑰K2=1111 1100

以上,通過密鑰得到了算法所需的子密鑰。

b)加密過程

首先是初始置換

① 對明文m=0001 0110做IP置換(IP={2,6,3,1,4,8,5,7}),得m’=0100 1001

接下來是標(biāo)準(zhǔn)的Feistel密碼結(jié)構(gòu),共有兩次循環(huán)。

第一次循環(huán)

② 記左半(高位)為Lm=0100,右半(低位)為Rm=1001

③ 對Rm做EP擴(kuò)展置換(EP={4,1,2,3,2,3,4,1}),得Rm’=1100 0011

④ Rm’與子密鑰K1按位異或(K1=0101 1111),得Rm’=1001 1100

⑤ Rm’左半1001(A1A2A3A4)進(jìn)入S0盒替代選擇得11(第4行A1A4 /第1列A2A3的數(shù)字3,再轉(zhuǎn)成二進(jìn)制11,A1A4中A1是數(shù)位高位),右半1100進(jìn)入S1盒替代選擇的01(第3行10/第3列10的數(shù)字1),組合后得Rm’=1101

⑥ 對Rm’做P4置換(P4={2,4,3,1}),得Rm’=1101

⑦ Rm’與Lm按位異或,得Lm’=1001

⑧ Lm’與Rm(最開始的那個Rm)組合得到輸出 1001(Lm’) 1001(Rm)

至此完成第一次循環(huán)。

⑨ 然后交換高低位,作為第二次循環(huán)的輸入,即1001(Rm)1001(Lm’)作為輸入

開始第二次循環(huán)

⑩ 記左半為Ln=1001,右半為Rn=1001

11 對Rn做EP擴(kuò)展置換(EP={4,1,2,3,2,3,4,1}),得Rn’=1100 0011

12 Rn’與子密鑰K2按位異或(K2=1111 1100),得Rn’=0011 1111

13 Rn’左半0011進(jìn)入S0盒替代選擇得10(第2行01/第2列01的數(shù)字2,再轉(zhuǎn)成二進(jìn)制10),右半1111進(jìn)入S1盒替代選擇的11(第4行11/第4列11的數(shù)字3,再轉(zhuǎn)成二進(jìn)制11),組合后得Rn’=1011

14 對Rn’做P4置換(P4={2,4,3,1}),得Rn’=0111

15 Rn’與Ln按位異或,得Ln’=1110

16 Ln’與Rn(最開始的那個Rn)組合得到輸出 1110(Ln’) 1001(Rn)

至此完成第二次循環(huán)

17 最后進(jìn)行逆初始置換對上面的輸出m’=1110 1001做IP-1置換得到密文m’=0111 0110.

OK,到這里就完成了將明文加密為密文,S-DES加密結(jié)束。

c)解密過程

解密過程與加密基本一致,就是密鑰使用順序是相反的,第一次循環(huán)使用K2第二次循環(huán)使用K1。

首先還是初始置換

① 對密文m=0111 0110做IP置換(IP={2,6,3,1,4,8,5,7}),得m’=1110 1001

Feistel密碼結(jié)構(gòu)

第一次循環(huán)

② 記左半(高位)為Lm=1110,右半(低位)為Rm=1001

③ 對Rm做EP擴(kuò)展置換(EP={4,1,2,3,2,3,4,1}),得Rm’=1100 0011

④ Rm’與子密鑰K2按位異或(K2=1111 1100),得Rm’=0011 1111

⑤ Rm’左半0011進(jìn)入S0盒替代選擇得10(第2行01/第2列01的數(shù)字2,再轉(zhuǎn)成二進(jìn)制10),右半1111進(jìn)入S1盒替代選擇的11(第4行11/第4列11的數(shù)字3,再轉(zhuǎn)成二進(jìn)制11),組合后得Rm’=1011

⑥ 對Rm’做P4置換(P4={2,4,3,1}),得Rm’=0111

⑦ Rm’與Lm按位異或,得Lm’=1001

⑧ Lm’與Rm(最開始的那個Rm)組合得到輸出 1001(Lm’) 1001(Rm)

至此完成第一次循環(huán)。

⑨ 然后交換高低位,作為第二次循環(huán)的輸入,即1001(Rm) 1001(Lm’)作為輸入

開始第二次循環(huán)

⑩ 記左半為Ln=1001,右半為Rn=1001

11 對Rn做EP擴(kuò)展置換(EP={4,1,2,3,2,3,4,1}),得Rn’=1100 0011

12 Rn’與子密鑰K1按位異或(K1=0101 1111),得Rn’=1001 1100

13 Rn’左半1001進(jìn)入S0盒替代選擇得11(第4行11/第1列00的數(shù)字3,再轉(zhuǎn)成二進(jìn)制11),右半1100進(jìn)入S1盒替代選擇的01(第3行10/第3列10的數(shù)字1),組合后得Rn’=1101

14 對Rn’做P4置換(P4={2,4,3,1}),得Rn’=1101

15 Rn’與Ln按位異或,得Ln’=0100

16 Ln’與Rn(最開始的那個Rn)組合得到輸出0100(Ln’) 1001(Rn)

至此完成第二次循環(huán)。

17 最后進(jìn)行逆初始置換

18 對上面的輸出m’=0100 1001做IP-1置換(IP-1={4,1,3,5,7,2,8,6})得到明文m’=0001 0110.

這樣就完成的S-DES的解密。

輸入

第一行輸入主密鑰

第二行輸入明文

輸出

輸出密文

輸入樣例

1100011110
00101000
0111111101
00010110

輸出樣例

10001010
01110110

解題

這里先貼代碼,因為當(dāng)初我按照一步一步來,沒有分模塊??赡苁且环N面向過程的編程。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strconv"
    "strings"
)

func id193(_r io.Reader, _w io.Writer) {
    in := bufio.NewReader(_r)
    out := bufio.NewWriter(_w)
    defer out.Flush()

    var key, text string
    P10 := []int{3, 5, 2, 7, 4, 10, 1, 9, 8, 6}
    P8 := []int{6, 3, 7, 4, 8, 5, 10, 9}
    P4 := []int{2, 4, 3, 1}
    IP := []int{2, 6, 3, 1, 4, 8, 5, 7}
    IP1 := []int{4, 1, 3, 5, 7, 2, 8, 6}
    S0 := [][]string{{"01", "01", "11", "10"},
        {"11", "10", "01", "00"},
        {"00", "10", "01", "11"},
        {"11", "01", "11", "10"}}
    S1 := [][]string{{"00", "01", "10", "11"},
        {"10", "00", "01", "11"},
        {"11", "00", "01", "00"},
        {"10", "01", "00", "11"}}
    EP := []int{4, 1, 2, 3, 2, 3, 4, 1}
    for {
        if _, err := fmt.Fscan(in, &key, &text); err != io.EOF {
            var convP10 strings.Builder
            for i := range P10 {
                fmt.Fprint(&convP10, string(key[P10[i]-1]))
            }
            Lk := convP10.String()[1:5] + convP10.String()[0:1]
            Rk := convP10.String()[6:] + convP10.String()[5:6]
            key2 := Lk + Rk
            var convP8 strings.Builder
            for i := range P8 {
                fmt.Fprint(&convP8, string(key2[P8[i]-1]))
            }
            K1 := convP8.String()
            key2 = Lk[2:5] + Lk[0:2] + Rk[2:5] + Rk[0:2]
            var K2_ strings.Builder
            for i := range P8 {
                fmt.Fprint(&K2_, string(key2[P8[i]-1]))
            }
            K2 := K2_.String()
            // fmt.Println(K1, K2)
            var convText_ strings.Builder
            for i := range IP {
                fmt.Fprint(&convText_, string(text[IP[i]-1]))
            }
            Lm := convText_.String()[:4]
            Rm := convText_.String()[4:]
            Rm_ := []int{}
            for i := range EP {
                v, err := strconv.Atoi(string(Rm[EP[i]-1]))
                if err == nil {
                    Rm_ = append(Rm_, v)
                }

            }
            // fmt.Println(Rm_)
            for i := range Rm_ {
                v, _ := strconv.Atoi(string(K1[i]))
                Rm_[i] ^= v
            }
            // fmt.Println(Rm_)
            Rm1 := S0[Rm_[0]*2+Rm_[3]][Rm_[1]*2+Rm_[2]]
            Rm2 := S1[Rm_[4]*2+Rm_[7]][Rm_[5]*2+Rm_[6]]
            var Lm_ []int
            Rm__ := Rm1 + Rm2
            for i := range P4 {
                tmp1, _ := strconv.Atoi(string(Rm__[P4[i]-1]))
                tmp2, _ := strconv.Atoi(string(Lm[i]))
                Lm_ = append(Lm_, tmp1^tmp2)
            }
            // fmt.Println(Lm_, Rm)
            Rn_ := []int{}
            for i := range EP {
                v, _ := strconv.Atoi(string(K2[i]))
                Rn_ = append(Rn_, Lm_[EP[i]-1]^v)
            }
            Rn1 := S0[Rn_[0]*2+Rn_[3]][Rn_[1]*2+Rn_[2]]
            Rn2 := S1[Rn_[4]*2+Rn_[7]][Rn_[5]*2+Rn_[6]]
            res := ""
            for i := range P4 {
                v, _ := strconv.Atoi(string((Rn1 + Rn2)[P4[i]-1]))

                b, _ := strconv.Atoi(string(Rm[i]))
                res += strconv.Itoa(v ^ b)
            }
            var ans strings.Builder
            fmt.Fprint(&ans, res)
            for i := range Lm_ {
                v := strconv.Itoa(Lm_[i])
                fmt.Fprint(&ans, v)
            }
            ans1 := ans.String()
            for i := range IP1 {
                fmt.Print(string(ans1[IP1[i]-1]))
            }
            fmt.Println()
        } else {
            break
        }
    }
}

func main() {
    id193(os.Stdin, os.Stdout)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容