• RC4的加密与解密实现

    前言

    RC4算法的特点是算法简单,运行速度快,而且密钥长度是可变的,可变范围为1-256字节(8-2048比特),在如今技术支持的前提下,当密钥长度为128比特时,用暴力法搜索密钥已经不太可行,所以可以预见RC4的密钥范围任然可以在今后相当长的时间里抵御暴力搜索密钥的攻击。实际上,如今也没有找到对于128bit密钥长度的RC4加密算法的有效攻击方法。

    C语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    //程序开始
    #include<stdio.h>
    #include<string.h>
    typedef unsigned longULONG;

    /*初始化函数*/
    void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len)
    {
    int i = 0, j = 0;
    char k[256] = { 0 };
    unsigned char tmp = 0;
    for (i = 0; i < 256; i++)
    {
    s[i] = i;//注意这里是否被更换
    k[i] = key[i % Len];
    }
    for (i = 0; i < 256; i++)
    {
    j = (j + s[i] + k[i]) % 256;
    tmp = s[i];
    s[i] = s[j];//交换s[i]和s[j]
    s[j] = tmp;
    }
    }

    /*加解密*/
    void rc4_crypt(unsigned char* s, unsigned char* Data, unsigned long Len)
    {
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;
    for (k = 0; k < Len; k++)
    {
    i = (i + 1) % 256;
    j = (j + s[i]) % 256;
    tmp = s[i];
    s[i] = s[j];//交换s[x]和s[y]
    s[j] = tmp;
    t = (s[i] + s[j]) % 256;
    Data[k] ^= s[t];
    }
    }

    int main()
    {
    unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box
    char key[256] = { "justfortest" };
    char pData[512] = "这是一个用来加密的数据Data";
    unsigned long len = strlen(pData);
    int i;

    printf("pData=%s\n", pData);
    printf("key=%s,length=%d\n\n", key, strlen(key));
    rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
    printf("完成对S[i]的初始化,如下:\n\n");
    for (i = 0; i < 256; i++)
    {
    printf("%02X", s[i]);
    if (i && (i + 1) % 16 == 0)putchar('\n');
    }
    printf("\n\n");
    for (i = 0; i < 256; i++)//用s2[i]暂时保留经过初始化的s[i],很重要的!!!
    {
    s2[i] = s[i];
    }
    printf("已经初始化,现在加密:\n\n");
    rc4_crypt(s, (unsigned char*)pData, len);//加密
    printf("pData=%s\n\n", pData);
    printf("已经加密,现在解密:\n\n");
    //rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥
    rc4_crypt(s2, (unsigned char*)pData, len);//解密
    printf("pData=%s\n\n", pData);
    return 0;
    }

    编译好程序,放进IDA的效果如图

    image-20220327211942702

    JAVA

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    public class rc4 {

    public static String decry_RC4(byte[] data, String key) {
    if (data == null || key == null) {
    return null;
    }
    return asString(RC4Base(data, key));
    }

    public static String decry_RC4(String data, String key) {
    if (data == null || key == null) {
    return null;
    }
    return new String(RC4Base(HexString2Bytes(data), key));
    }

    public static byte[] encry_RC4_byte(String data, String key) {
    if (data == null || key == null) {
    return null;
    }
    byte b_data[] = data.getBytes();
    return RC4Base(b_data, key);
    }

    public static String encry_RC4_string(String data, String key) {
    if (data == null || key == null) {
    return null;
    }
    return toHexString(asString(encry_RC4_byte(data, key)));
    }

    private static String asString(byte[] buf) {
    StringBuffer strbuf = new StringBuffer(buf.length);
    for (int i = 0; i < buf.length; i++) {
    strbuf.append((char) buf[i]);
    }
    return strbuf.toString();
    }

    private static byte[] initKey(String aKey) {
    byte[] b_key = aKey.getBytes();
    byte state[] = new byte[256];

    for (int i = 0; i < 256; i++) {
    state[i] = (byte) i;
    }
    int index1 = 0;
    int index2 = 0;
    if (b_key == null || b_key.length == 0) {
    return null;
    }
    for (int i = 0; i < 256; i++) {
    index2 = ((b_key[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
    byte tmp = state[i];
    state[i] = state[index2];
    state[index2] = tmp;
    index1 = (index1 + 1) % b_key.length;
    }
    return state;
    }

    private static String toHexString(String s) {
    String str = "";
    for (int i = 0; i < s.length(); i++) {
    int ch = (int) s.charAt(i);
    String s4 = Integer.toHexString(ch & 0xFF);
    if (s4.length() == 1) {
    s4 = '0' + s4;
    }
    str = str + s4;
    }
    return str;// 0x表示十六进制
    }

    private static byte[] HexString2Bytes(String src) {
    int size = src.length();
    byte[] ret = new byte[size / 2];
    byte[] tmp = src.getBytes();
    for (int i = 0; i < size / 2; i++) {
    ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
    }
    return ret;
    }

    private static byte uniteBytes(byte src0, byte src1) {
    char _b0 = (char) Byte.decode("0x" + new String(new byte[] { src0 })).byteValue();
    _b0 = (char) (_b0 << 4);
    char _b1 = (char) Byte.decode("0x" + new String(new byte[] { src1 })).byteValue();
    byte ret = (byte) (_b0 ^ _b1);
    return ret;
    }

    private static byte[] RC4Base(byte[] input, String mKkey) {
    int x = 0;
    int y = 0;
    byte key[] = initKey(mKkey);
    int xorIndex;
    byte[] result = new byte[input.length];

    for (int i = 0; i < input.length; i++) {
    x = (x + 1) & 0xff;
    y = ((key[x] & 0xff) + y) & 0xff;
    byte tmp = key[x];
    key[x] = key[y];
    key[y] = tmp;
    xorIndex = ((key[x] & 0xff) + (key[y] & 0xff)) & 0xff;
    result[i] = (byte) (input[i] ^ key[xorIndex]);
    }
    return result;
    }

    public static void main(String[] args) {
    String inputStr = "goods";
    String str = encry_RC4_string(inputStr, "justfortest");
    System.out.println(str);
    System.out.println(decry_RC4(str, "justfortest"));
    }
    }

    javascript

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    function rc4(data, key) {
    var seq = Array(256);//int
    var das = Array(data.length);//code of data
    for (var i = 0; i < 256; i++) {
    seq[i] = i;
    var j = (j + seq[i] + key.charCodeAt(i % key.length)) % 256;
    var temp = seq[i];
    seq[i] = seq[j];
    seq[j] = temp;
    }
    for (var i = 0; i < data.length; i++) {
    das[i] = data.charCodeAt(i);
    }

    for (var x = 0; x < das.length; x++) {
    var i = (i + 1) % 256;
    var j = (j + seq[i]) % 256;
    var temp = seq[i];
    seq[i] = seq[j];
    seq[j] = temp;
    var k = (seq[i] + (seq[j] % 256)) % 256;
    das[x] = String.fromCharCode(das[x] ^ seq[k]);
    }
    return das.join('');
    }
    }
    //var data = "I am data";
    //var key = "justfortest";
    //var a1 = rc4(data, key);
    //var data1 = rc4(a1, key);

    链接

    基于以上内容实现的在线RC4加密解密工具 https://kuangtant.gitee.io/tools/rc4/

    上一篇:
    Win32笔记-基础
    下一篇:
    初始花指令
    本文目录
    本文目录