加密解密

Rc4的加密和解密

2019-11-10  本文已影响0人  麦田夕阳

Rc4:

密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。

Rc4加密的原理:

主要包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)两大部分。假设S-box的长度为256,密钥长度为Len
在初始化的过程中,密钥的主要功能是将S-box搅乱,i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。而不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,将S-box和明文进行xor运算,得到密文,解密过程也完全相同。

1.初始化秘钥:根据输入的秘钥key,使用密钥调度算法(KSA)生成一个256字节的sbox。
2.再通过伪随机数生成算法(PRGA)得到密钥流(keystream)
3.加密:密钥流与明文进行异或运算得到密文
4.解密:秘文与密钥流进行异或运算得到明文

java的实现Rc4的代码:

public class Rc4Util {
    private static final int SBOX_LENGTH = 256;
    private static final int KEY_MIN_LENGTH = 6;
    /**
     * 加密
     *
     * @param message
     * @param key
     * @return
     */
    public static byte[] encryptMessage(String message, String key) {
        byte[] crypt = crypt(message.getBytes(StandardCharsets.UTF_8), key);
        return crypt;
    }
    /**
     * 解密
     *
     * @param message
     * @param key
     * @return
     */
    public static String decryptMessage(byte[] message, String key) {
        byte[] msg = crypt(message, key);
        return new String(msg, StandardCharsets.UTF_8);
    }
    public static byte[] crypt(final byte[] msg, String key) {
        byte[] keyBytes = getKey("123456");
        if (keyBytes == null) {
            return null;
        }
        //SBox
        int[] sbox = initSBox(keyBytes);
        byte[] code = new byte[msg.length];
        int i = 0;
        int j = 0;
        for (int n = 0; n < msg.length; n++) {
            i = (i + 1) % SBOX_LENGTH;
            j = (j + sbox[i]) % SBOX_LENGTH;
            swap(i, j, sbox);
            int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
            code[n] = (byte) (rand ^ msg[n]);
        }
        return code;
    }
    private static int[] initSBox(byte[] key) {
        int[] sbox = new int[SBOX_LENGTH];
        int j = 0;

        for (int i = 0; i < SBOX_LENGTH; i++) {
            sbox[i] = i;
        }

        for (int i = 0; i < SBOX_LENGTH; i++) {
            j = (j + sbox[i] + (key[i % key.length]) & 0xFF) % SBOX_LENGTH;
            swap(i, j, sbox);
        }
        return sbox;
    }
    private static void swap(int i, int j, int[] sbox) {
        int temp = sbox[i];
        sbox[i] = sbox[j];
        sbox[j] = temp;
    }
    public static byte[] getKey(String key) {
        if (key.length() <KEY_MIN_LENGTH || key.length() > SBOX_LENGTH) {
            System.out.println("Key length has to be between "
                    + KEY_MIN_LENGTH + ", " + (SBOX_LENGTH - 1));
            return null;
        }
        return key.getBytes();
    }
    public static void main(String[] args) {
        byte[] en = Rc4Util.encryptMessage("Rc4加密", "123456");
        String base = Base64.getEncoder().encodeToString(en);
        System.out.println(base);
        String d = Rc4Util.decryptMessage(Base64.getDecoder().decode(base), "123456");
        System.out.println(d);
    }
}

上一篇下一篇

猜你喜欢

热点阅读