Kamis, 15 Desember 2016

RC6 Java Code



package lp2maray.com;

public class RC6 {

    private int w=32, r=20;
    private int Pw=0xb7e15163, Qw=0x9e3779b9;
    private int[] S;
//    private String filename;
//    private String directory;
//    private String fileNameEncrypt;
//    private String extension;
 
//    public void setFile(String directory, String filename, String extens){
//        this.fileNameEncrypt = directory + "/" + "en." + filename + "." + extens;
//        System.out.println("fileNameEncrypt="+fileNameEncrypt);
//    }
 
    private int[] convBytesWords(byte[] key, int u, int c) {
        int[] tmp = new int[c];
        for (int i = 0; i < tmp.length; i++)
            tmp[i] = 0;
     
        for (int i = 0, off = 0; i < c; i++)
            tmp[i] = ((key[off++] & 0xFF)) | ((key[off++] & 0xFF) << 8)
                    | ((key[off++] & 0xFF) << 16) | ((key[off++] & 0xFF) << 24);
     
        return tmp;
    }
 
 
    //penjadwalan kunci RC 6 mencampurkan aray S dengan L
    private int[] generateSubkeys(byte[] key) {
        int u = w / 8;
        int c = key.length / u;
        int t = 2 * r + 4;
     
        int[] L = convBytesWords(key, u, c);
     
        int[] S = new int[t];
        S[0] = Pw;
        for (int i = 1; i < t; i++)
            S[i] = S[i - 1] + Qw;
     
        int A = 0;
        int B = 0;
        int k = 0, j = 0;
     
        int v = 3 * Math.max(c, t);
     
        for (int i = 0; i < v; i++) {
            A = S[k] = rotl((S[k] + A + B), 3);
            B = L[j] = rotl(L[j] + A + B, A + B);
            k = (k + 1) % t;
            j = (j + 1) % c;
        }
        return S;
    }
 
    //penggeseran bit kekiri
    private int rotl(int val, int pas) {
        return (val << pas) | (val >>> (32 - pas));
    }
 
    //penggeseran bit ke kanan
    private int rotr(int val, int pas) {
        return (val >>> pas) | (val << (32-pas));
    }
 
 
    //memecah blok cipertext kedalam 4 register
    private byte[] decryptBloc(byte[] input) {
        byte[] tmp = new byte[input.length];
        int t,u;
        int aux;
        int[] data = new int[input.length/4];
     
        for(int i =0;i<data.length;i++)
            data[i] = 0;
        int off = 0;
     
        for(int i=0;i<data.length;i++){
            data[i] = ((input[off++]&0xff))|
                    ((input[off++]&0xff) << 8) |
                    ((input[off++]&0xff) << 16) |
                    ((input[off++]&0xff) << 24);
        }
     
        int A = data[0],B = data[1],C = data[2],D = data[3];
     
        C = C - S[2*r+3];
        A = A - S[2*r+2];
        for(int i = r;i>=1;i--) {
            aux = D;
            D = C;
            C = B;
            B = A;
            A = aux;
         
            u = rotl(D*(2*D+1),5);
            t = rotl(B*(2*B + 1),5);
            C = rotr(C-S[2*i + 1],t) ^ u;
            A = rotr(A-S[2*i],u) ^ t;
        }
     
        D = D - S[1];
        B = B - S[0];
     
        data[0] = A;data[1] = B;data[2] = C;data[3] = D;
     
        for(int i = 0;i<tmp.length;i++) {
            tmp[i] = (byte)((data[i/4] >>> (i%4)*8) & 0xff);
        }
        return tmp;
    }
 
    //memecah blok plaintext kedalam 4 register
    private byte[] encryptBloc(byte[] input) {
        byte[] tmp = new byte[input.length];
        int t,u;
        int aux;
        int[] data = new int[input.length/4];
        for(int i =0;i<data.length;i++)
            data[i] = 0;
        int off = 0;
        for(int i=0;i<data.length;i++) {
            data[i] = ((input[off++]&0xff))|
                    ((input[off++]&0xff) << 8) |
                    ((input[off++]&0xff) << 16) |
                    ((input[off++]&0xff) << 24);
        }
     
        int A = data[0],B = data[1],C = data[2],D = data[3];
     
        B = B + S[0];
        D = D + S[1];
        for(int i = 1;i<=r;i++) {
            t = rotl(B*(2*B+1),5);
            u = rotl(D*(2*D+1),5);
            A = rotl(A^t,u)+S[2*i];
            C = rotl(C^u,t)+S[2*i+1];
         
            aux = A;
            A = B;
            B = C;
            C = D;
            D = aux;
        }
        A = A + S[2*r+2];
        C = C + S[2*r+3];
     
        data[0] = A;data[1] = B;data[2] = C;data[3] = D;
     
        for(int i = 0;i<tmp.length;i++) {
            tmp[i] = (byte)((data[i/4] >>> (i%4)*8) & 0xff);
        }
        return tmp;
    }
 
    //proses padding awal dalam penjadwalan kunci
    private static  byte[] paddingKey(byte[] key){
        int l=0;
        if(key.length==1){
            l=3;
        }
        else
            l=key.length%4;
        byte[]key2=new byte[key.length+l];
     
        for(int i=0;i<key2.length;i++){
            if(i<key.length){
                key2[i]=key[i];
            }
            else{
                key2[i]=0;
            }
        }
        return key2;
    }
 
    //fungsi untuk melakukan enkripsi RC6
    public  byte[] encrypt(byte[] data, byte[] key) {
        byte[] bloc = new byte[16];
        key = paddingKey(key);
        S = generateSubkeys(key);

        int lenght = 16 - data.length % 16;
        byte[] padding = new byte[lenght];
        padding[0] = (byte) 0x80;

        for (int i = 1; i < lenght; i++)
                padding[i] = 0;
        int count = 0;
        byte[] tmp = new byte[data.length+lenght];

        int i;
        for(i=0;i<data.length+lenght;i++) {
            if(i>0 && i%16 == 0) {
                bloc = encryptBloc(bloc);
                System.arraycopy(bloc, 0, tmp, i-16, bloc.length);
            }

            if (i < data.length)
                bloc[i % 16] = data[i];
            else {
                bloc[i % 16] = padding[count];
                count++;
                if(count>lenght-1) count = 1;
            }
        }
        bloc = encryptBloc(bloc);
        System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);
        return tmp;              
    }

    //fungsi untuk melakukan dekripsi RC6
    public  byte[] decrypt(byte[] data, byte[] key) {
        byte[] tmp = new byte[data.length];
        byte[] bloc = new byte[16];
        key = paddingKey(key);
        S = generateSubkeys(key);

        int i;
        for(i=0;i<data.length;i++) {
            if(i>0 && i%16 == 0) {
                bloc = decryptBloc(bloc);
                System.arraycopy(bloc, 0, tmp, i-16, bloc.length);
            }

            if (i < data.length)
                bloc[i % 16] = data[i];
        }

        bloc = decryptBloc(bloc);
        System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);

        tmp = deletePadding(tmp);
        return tmp;
    }

    //proses penghilangan padding pada key
    private byte[] deletePadding(byte[] input) {
        int count = 0;

        int i = input.length - 1;
        while (input[i] == 0) {
                count++;
                i--;
        }

        byte[] tmp = new byte[input.length - count - 1];
        System.arraycopy(input, 0, tmp, 0, tmp.length);
        return tmp;
    }
     
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer sb = new StringBuffer(b.length * 2);
        for (int i = 0; i < b.length; i++) {
                int v = b[i] & 0xff;
                if (v < 16) {
                        sb.append('0');
                }
                sb.append(Integer.toHexString(v));
        }
        return sb.toString().toUpperCase();
    }

//    public byte[] encrypt(String content, byte[] bytes) {
//        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//    }
//
//    public String decrypt(byte[] bcs, String kunci) {
//        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//    }
}

2 komentar: