zoukankan      html  css  js  c++  java
  • sdes简单实例

    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{igoplus}F(R,SK),R))

    (F(p,k)):

    1. 对P做 (E/P) 扩展置换如
    (E/P)
    4 1 2 3 2 3 4 1
    1. (P = P igoplus 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

  • 相关阅读:
    白天写代码,晚上摆地摊!9年前摆地摊学会了这些道理...
    啪啪,打脸了!领导说:try-catch必须放在循环体外!
    阿里巴巴为什么让初始化集合时必须指定大小?
    永远不要使用双花括号初始化实例,否则就会OOM!
    限流的6大狠招,附详细代码和评测结果
    HashMap 的 7 种遍历方式与性能分析!(强烈推荐)
    String性能提升10倍的几个方法!(源码+原理分析)
    9个小技巧让你的 if else看起来更优雅
    用了自定义Banner后,SpringBoot瞬间变的高大上了...
    别再问我 new 字符串创建了几个对象了!我来证明给你看!
  • 原文地址:https://www.cnblogs.com/xxrlz/p/12503274.html
Copyright © 2011-2022 走看看