首页 > 技术文章 > sdes简单实例

xxrlz 2020-03-16 13:21 原文

sdes

key:1100011110
plaintext:00101000

生成k1,k2

key-> k1(4bits), k2(4bits)

P10,P8: 长度为10和8的置换

P10:

1 2 3 4 5 6 7 8 9 10
3 5 2 7 4 10 1 9 8 6

P8:

1 2 3 4 5 6 7 8
6 3 7 4 8 5 10 9

\(k1 = P8(shift(P10(k)))\)
\(k2 = P8(shift^3(P10(k)))\)

Bit # 1 2 3 4 5 6 7 8 9 10
\(K\) 1 1 0 0 0 1 1 1 1 0
\(P10(K)\) 0 0 1 1 0 0 1 1 1 1
\(Shif t(P10(K))\) 0 1 1 0 0 1 1 1 1 0
\(P8(Shif t(P10(K)))\) 1 1 1 0 1 0 0 1
Bit # 1 2 3 4 5 6 7 8 9 10
\(K\) 1 1 0 0 0 1 1 1 1 0
\(P10(K)\) 0 0 1 1 0 0 1 1 1 1
\(Shift^3(P10(K))\) 1 0 0 0 1 1 1 0 1 1
\(P8(Shift^3(P10(K)))\) 1 0 1 0 0 1 1 1

k1 = {1110 1001} and k2 = {1010 0111}

加密

  1. \(p = IP(p)\)
  2. \(p = f_k(p,k1)\)
  3. \(p = SW(p)\)
  4. \(p = f_k(p,k2)\)
  5. \(p = IP^{-1}(p)\)

解密将2,4互换即可

把P写成 \(P=(L,R)\)

\(IP\):8位置换(2,6,3,1,4,8,5,7)
\(IP^{-1}\): IP的逆操作{4,1,3,5,7,2,8,6}

\(SW\): \(SW(P) = SW(L,R) = (R,L)\), 左右bit互换

\(f_k\): \(f_k(L,R) = (L{\bigoplus}F(R,SK),R)\)

\(F(p,k)\):

  1. 对P做 \(E/P\) 扩展置换如
\(E/P\)
4 1 2 3 2 3 4 1
  1. \(P = P \bigoplus k\)
  2. P(L,R) 左右四个bits分别进入两个S盒得到左右两个bits共4bits
  3. 再对P做一次4位置换

S盒:

S盒操作如下:第一个和第四个输入作为一个2位数指定S盒中的一行,第二和第三个输入作为一个2位数指定S盒中的一列。比如0010,则输出是S盒的第一行第二列这里是3(二进制的11),类似的 和的值找到在第二个S盒中的值。

实现

import java.io.IOException;  
public class SimpleDES {  
    /**
     * @param args
     */  
    // two keys K1 and K2  
    static int K1=0;  
    static int K2=0;  
    /*some parameters*/  
    static int P10[]=new int[]{3,5,2,7,4,10,1,9,8,6};  
    static int P8[]=new int[]{6,3,7,4,8,5,10,9};  
    static int P4[]=new int[]{2,4,3,1};  
    static int IP[]=new int[]{2,6,3,1,4,8,5,7};  
    static int IPI[]=new int[]{4,1,3,5,7,2,8,6};  
    static int EP[]=new int[]{4,1,2,3,2,3,4,1};  
    static int S0[][]={  
         {1,0,3,2},  
         {3,2,1,0},  
         {0,2,1,3},  
         {3,1,3,2},  
    };  
    static int S1[][]={  
         {0,1,2,3},  
         {2,0,1,3},  
         {3,0,1,0},  
         {2,1,0,3},  
    };  
    //根据数组交换  
    static int Permute(int num,int p[],int pmax){  
        int result=0;  
        for(int i=0;i<p.length;i++){  
            result<<=1;  
            result|=(num>>(pmax-p[i]))&1;  
        }  
        return result;  
    }  
    //生成k1,k2  
    static void SDES(String Key){  
        int K=Integer.parseInt(Key,2);  
        K=Permute(K,P10,10);  
        int th=0,tl=0;  
        th=(K>>5)&0x1f;//取Key的高5位  
        tl=K&0x1f;     //取Key的低5位  
        //LS-1  
        th=((th&0xf)<<1) | ((th & 0x10) >> 4);//循环左移一位  
        tl=((tl&0xf)<<1) | ((tl & 0x10) >> 4);//循环左移一位  
        K1=Permute(( th << 5)| tl,P8,10);     //生成K1  
        System.out.println("K1:"+Integer.toString(K1,2));  
        //LS-2  
        th=((th & 0x07)<< 2) |((th & 0x18) >> 3);//循环左移二位  
        tl=((tl & 0x07)<< 2) |((tl & 0x18) >> 3);//循环左移二位  
        K2=Permute((th<<5) | tl,P8,10);          //生成K2  
        System.out.println("K2:"+Integer.toString(K2,2));  
    }  
    /*
        1. E/P
        2. P^K
        3. P = S1(L)|S2(R)
        4. P = P4(P)
    */
    static int F(int R,int K){  
        int t=Permute(R,EP,4)^K; // 1,2  
        int t0=(t>>4)& 0xf;  
        int t1=t&0xf;  
        t0= S0[((t0 & 0x8)>>2) | (t0 & 1)] [(t0>>1)&0x3];  
        t1= S1[((t1 & 0x8)>>2) | (t1 & 1)] [(t1>>1)&0x3];   // 3
        t= Permute((t0<<2)|t1,P4,4);  // 4
        return t;  
    }  
    //fk函数   fk = (L^F(r,k),r)
    static int fk(int input,int k){  
        int l=(input>>4) & 0xf;  
        int r=input & 0xf;  
        return ((l^F(r,k))<< 4)| r;  
    }  
    //switch function  左右移位
    static int SW(int x)  
    {  
         return ((x&0xf)<<4) | ((x>>4)&0xf);  
    }  
    //加密  
    static String encrypt(String input){  
        int m=Integer.parseInt(input, 2);  
        m=Permute(m,IP,8);  
        m=fk(m,K1);  
        m=SW(m);  
        m=fk(m,K2);  
        m=Permute(m,IPI,8);  
        return Integer.toString(m, 2);  
    }  
    //解密  
    static String decrypt(String input){  
        int m=Integer.parseInt(input, 2);  
        m=Permute(m,IP,8);  
        m=fk(m,K2);  
        m=SW(m);  
        m=fk(m,K1);  
        m=Permute(m,IPI,8);  
        return Integer.toString(m, 2);  
    }  
    public static void main(String[] args) throws IOException {  
        // TODO Auto-generated method stub  
        String plaintext,ciphertext,key;  
        java.util.Scanner scan = new java.util.Scanner(System.in);  
        System.out.println("1:加密,2:解密,3:退出,请输入一个数字来选择:");  
        int  mode=scan.nextInt();  
        while(true){  
            if(mode==1){  
                System.out.println("请输入明文:");  
                plaintext=scan.next();  
                System.out.println("请输入密钥:");  
                key=scan.next();  
                SDES(key);  
                ciphertext=encrypt(plaintext);  
                //如果密文不足8位,补足8位  
                if(ciphertext.length()<8){  
                    for(int i=0;i<8-ciphertext.length();i++)  
                        ciphertext="0"+ciphertext;  
                }  
                System.out.println("加密后的密文为:"+ciphertext);  
            }  
            else if(mode==2){  
                System.out.println("请输入密文:");  
                ciphertext=scan.next();  
                System.out.println("请输入密钥:");  
                key=scan.next();  
                SDES(key);  
                plaintext=decrypt(ciphertext);  
                if(plaintext.length()<8){  
                    for(int i=0;i<8-plaintext.length();i++)  
                        plaintext="0"+plaintext;  
                }  
                System.out.println("解密后的明文为:"+plaintext);  
            }  
            else if(mode==3) break;  
            System.out.println("1:加密,2:解密,3:退出,请输入一个数字来选择:");  
            mode=scan.nextInt();  
        }  
    }  
}  

引用:博客,java

推荐阅读