Rc 4の暗号化と復号化

3187 ワード

Rc4:
暗号学では、RC 4(Rivest Cipher 4からの略称)はストリーム暗号化アルゴリズムであり、鍵長が可変である.復号化には同じ鍵が使用されるため、対称暗号化アルゴリズムにも属します.RC 4は有線等価暗号化(WEP)に採用された暗号化アルゴリズムであり、かつてTLSで採用可能なアルゴリズムの一つでもあった.
Rc 4暗号化の原理:
主に初期化アルゴリズム(KSA)と擬似ランダムサブ暗号生成アルゴリズム(PRGA)の2つの大部分を含む.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の実装Rc 4のコード:
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()  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);
    }
}