Java和Php的RC4加解密互通

Java RC4加解密算法

    public static class RC4Util {

        /**
         * RC4加密,将加密后的数据进行哈希
         * @param data 需要加密的数据
         * @param key 加密密钥
         * @param chartSet 编码方式
         * @return 返回加密后的数据
         * @throws UnsupportedEncodingException
         */
        public static String encryRC4String(String data, String key, String chartSet) throws UnsupportedEncodingException {
            if (data == null || key == null) {
                return null;
            }
            return bytesToHex(encryRC4Byte(data, key, chartSet));
        }

        /**
         * RC4加密,将加密后的字节数据
         * @param data 需要加密的数据
         * @param key 加密密钥
         * @param chartSet 编码方式
         * @return 返回加密后的数据
         * @throws UnsupportedEncodingException
         */
        public static byte[] encryRC4Byte(String data, String key, String chartSet) throws UnsupportedEncodingException {
            if (data == null || key == null) {
                return null;
            }
            if (chartSet == null || chartSet.isEmpty()) {
                byte bData[] = data.getBytes();
                return RC4Base(bData, key);
            } else {
                byte bData[] = data.getBytes(chartSet);
                return RC4Base(bData, key);
            }
        }

        /**
         * RC4解密
         * @param data 需要解密的数据
         * @param key 加密密钥
         * @param chartSet 编码方式
         * @return 返回解密后的数据
         * @throws UnsupportedEncodingException
         */
        public static String decryRC4(String data, String key,String chartSet) throws UnsupportedEncodingException {
            if (data == null || key == null) {
                return null;
            }
            return new String(RC4Base(hexToByte(data), key),chartSet);
        }

        /**
         * RC4加密初始化密钥
         * @param aKey
         * @return
         */
        private static byte[] initKey(String aKey) {
            byte[] bkey = 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 (bkey.length == 0) {
                return null;
            }
            for (int i = 0; i < 256; i++) {
                index2 = ((bkey[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
                byte tmp = state[i];
                state[i] = state[index2];
                state[index2] = tmp;
                index1 = (index1 + 1) % bkey.length;
            }
            return state;
        }


        /**
         * 字节数组转十六进制
         * @param bytes
         * @return
         */
        public static String bytesToHex(byte[] bytes) {
            StringBuffer sb = new StringBuffer();
            for(int i = 0; i < bytes.length; i++) {
                String hex = Integer.toHexString(bytes[i] & 0xFF);
                if(hex.length() < 2){
                    sb.append(0);
                }
                sb.append(hex);
            }
            return sb.toString();
        }

        /**
         * 十六进制转字节数组
         * @return
         */
        public static byte[] hexToByte(String inHex){
            int hexlen = inHex.length();
            byte[] result;
            if (hexlen % 2 == 1){
                hexlen++;
                result = new byte[(hexlen/2)];
                inHex="0"+inHex;
            }else {
                result = new byte[(hexlen/2)];
            }
            int j=0;
            for (int i = 0; i < hexlen; i+=2){
                result[j]=(byte)Integer.parseInt(inHex.substring(i,i+2),16);
                j++;
            }
            return result;
        }

        /**
         * RC4解密
         * @param input
         * @param mKkey
         * @return
         */
        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;
        }
    }

PHP RC4加解密算法

/**
 * RC4位置替换
 * @param $a
 * @param $b
 */
function _swap(&$a, &$b)
{
    $tmp = $a;
    $a = $b;
    $b = $tmp;
}

/**
 * RC4 加密
 * @param $key
 * @param $data
 * @param bool $decrypted
 * @return string
 */
function _encrypted($key, $data, $decrypted = false)
{
    $keyLength = strlen($key);
    $S = array();
    for ($i = 0; $i < 256; $i++) $S[$i] = $i;
    $j = 0;
    for ($i = 0; $i < 256; $i++) {
        $j = ($j + $S[$i] + ord($key[$i % $keyLength])) % 256;
        _swap($S[$i], $S[$j]);
    }
    $dataLength = strlen($data);
    $output = "";
    for ($a = $j = $i = 0; $i < $dataLength; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $S[$a]) % 256;
        _swap($S[$a], $S[$j]);
        $k = $S[(($S[$a] + $S[$j]) % 256)];
        $output .= chr(ord($data[$i]) ^ $k);
    }
    return ($decrypted) ? $output : bin2hex($output);
}

/**
 *  RC4 解密
 * @param $key
 * @param $data
 * @return string
 */
function _decrypted($key, $data)
{
    if (function_exists("hex2bin")) {
        return _encrypted($key, hex2bin($data), true);

    } else {
        return _encrypted($key, pack("H*", $data), true); // hex2bin php5.4才支持

    }

}

版权声明:本文为m0_50217253原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。