RC4解密, php能解密成功,java解密乱码,为什么?

KerryLi 发布于 2017/06/15 16:17
阅读 861
收藏 1

php代码:

<?php
$json=file_get_contents('php://input');
if ($json) {

    //开始RC4解密
    $key = substr($json,0,16);                               
    $json = rc4($key, substr($json,16));

 

function rc4($pwd, $data)//$pwd密钥 $data需加密字符串
{
        $key[] ="";
        $box[] ="";
        $cipher="";
        $pwd_length = strlen($pwd);
        $data_length = strlen($data);
     
        for ($i = 0; $i < 256; $i++)
        {
            $key[$i] = ord($pwd[$i % $pwd_length]);
            $box[$i] = $i;
        }
     
        for ($j = $i = 0; $i < 256; $i++)
        {
            $j = ($j + $box[$i] + $key[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
     
        for ($a = $j = $i = 0; $i < $data_length; $i++)
        {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
     
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
     
            $k = $box[(($box[$a] + $box[$j]) % 256)];
            $cipher .= chr(ord($data[$i]) ^ $k);
        }
       // var_dump($cipher);
        //exit();
        return $cipher;
}

 

java代码:

    @RequestMapping("/acc")
    public void acc1(HttpServletRequest request,HttpServletResponse response) throws Exception{
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        System.out.println(sdf.format(new Date())+"-->post begin.......");
         BufferedReader reader = new BufferedReader(
                 new InputStreamReader(request.getInputStream(),"UTF-8"));
         String line=null;
         StringBuilder buffer = new StringBuilder();
         while((line = reader.readLine())!=null){
                 buffer.append(line);
               }
         System.out.println("recive:   "+buffer.toString());
         String key = buffer.toString().substring(0, 16);
         String content =  buffer.toString().substring(16);
         System.out.println("before 16 string:    "+key);
         System.out.println("content :    "+content);
         System.out.println("decrypt :       "+RC4.HloveyRC4(content, key));
         
        System.out.println(sdf.format(new Date())+"-->post end.......");
    }

java rc4代码:

public static String HloveyRC4(String aInput,String aKey) {   
        int[] iS = new int[256];   
        byte[] iK = new byte[256];   
        for (int i=0;i<256;i++)   
            iS[i]=i;   
        int j = 1;   
        for (short i= 0;i<256;i++) {   
            iK[i]=(byte)aKey.charAt((i % aKey.length()));   
        }   
        j=0;   
        for (int i=0;i<255;i++){   
            j=(j+iS[i]+iK[i]) % 256;   
            int temp = iS[i];   
            iS[i]=iS[j];   
            iS[j]=temp;   
        }   
        int i=0; j=0;   
        char[] iInputChar = aInput.toCharArray();   
        char[] iOutputChar = new char[iInputChar.length];   
        for(short x = 0;x<iInputChar.length;x++) {   
            i = (i+1) % 256;   
            j = (j+iS[i]) % 256;   
            int temp = iS[i];   
            iS[i]=iS[j];   
            iS[j]=temp;   
            int t = (iS[i]+(iS[j] % 256)) % 256;   
            int iY = iS[t];   
            char iCY = (char)iY;   
            iOutputChar[x] =(char)( iInputChar[x] ^ iCY) ;      
        }   
        return new String(iOutputChar);   
    }  

正确解密结果应该是:

13MSFCS116120007532C:5B:B8:41:92:781497511080
13MSFCS1161200075310:0B:A9:6A:E1:A01497511081
13MSFCS11612000753F0:25:B7:81:0E:B21497511081
13MSFCS1161200075380:3F:5D:0B:16:411497511081
13MSFCS1161200075314:5F:94:B3:8C:6B1497511081
13MSFCS116120007535E:D8:0E:D8:ED:7F1497511081
13MSFCS11612000753D2:44:66:7C:FD:951497511081
13MSFCS116120007536C:8D:C1:50:3C:B11497511082
13MSFCS11612000753EC:55:F9:C1:B0:E11497511082

 

java解密直接乱码了:

php可以解密成功,大神们,是不是这个java的RC4解密算法有问题,还是获取request的inputstream有问题。java rc4代码,网上搜的。

 

加载中
0
KerryLi
KerryLi

主要问题是java接收数据的时候,需要获取byte数组的方式接收,因为设备使用C++语言写的,

Java应当先把字符串转换为byte[], 然后再去参与解密算法; PHP算法正确,是因为它使用的的strlen函数, 会把一个中文字符当成3个byte来看(utf-8),而JAVA错误是因为你使用的是 toCharArray, 一个中文等于一个char;一个是对byte数组进行解密,一个是对char数组进行解密,结果自然不同。

更改后java接收端代码:

            in = request.getInputStream();
            byte[] getArr = readBytes(in, request.getContentLength());
            byte[] key = new byte[16];
            System.arraycopy(getArr, 0, key, 0, key.length);
            System.out.println("key:"+new String(key));
            
            int contentLength = request.getContentLength()-16;
            byte[] content = new byte[contentLength];
            System.arraycopy(getArr, 16, content, 0, content.length);
            System.out.println("content"+new String(content));
            
            String result = RC4T2.decry_RC4(content, new String(key));
            System.out.println("RC4 decrypt:"+result);
            
 更改后解密算法代码:

public class RC4T2 {
    
        public static String decry_RC4(byte[] data, String key) {
            if (data == null || key == null) {
                return null;
            }
            return asString(RC4Base(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[] 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;
        }

       }

解密结果:

RC4decrypt:13 MSFCS11612000203 B4:8B:19:E3:16:C4 -63 1.00,22.00 1500430087 12 MSFCS11612000203 A6:34:D9:B0:7B:FB DIRECT-CCZHTANGHAORAN2msQU 11 WPA2 -74 1.00,22.00 1500430087 12 MSFCS11612000203 00:11:B5:11:22:9A freewifi-yhnw 1 WPA2 -71 1.00,22.00 1500430087 12 MSFCS11612000203 80:F6:2E:99:0F:D0 SZB_1F 1 WP
20170719102921-->acc post end.......

返回顶部
顶部