其它系统给我们这个系统发过来用户名和密码,只能以URL形式发送,必须加密,目前采用的是RC4算法。
但RC4加密后的数据存在乱码字符,且通过URL形式传送过来时需要转换成十六进制。
于是产生问题:
通过RC4加密后的数据再转换成十六进制后,解密时通过16进制转换后再进行解密后的数据与加密前的数据不一致
public class 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 = 0;
for (short i = 0; i < 256; i++) {
iK[i] = (byte) aKey.charAt((i % aKey.length())); // charAt函数的作用是返回指定索引位置处的字符
}
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);
} public static String EncryptRC4(String aInput, String aKey) {
String str = HloveyRC4(aInput, aKey);
str = bin2hex(str);
return str;
} public static String DecryptRC4(String aInput, String aKey) {
aInput = hex2bin(aInput);
String str = HloveyRC4(aInput, aKey);
return str;
} /**
 * 字符串转换成十六进制值
 * 
 * @param bin
 *            String 我们看到的要转换成十六进制的字符串
 * @return
 */
public static String bin2hex(String bin) {
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = bin.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
}
return sb.toString();
} /**
 * 十六进制转换字符串
 * 
 * @param hex
 *            String 十六进制
 * @return String 转换后的字符串
 */
public static String hex2bin(String hex) {
String digital = "0123456789ABCDEF";
char[] hex2char = hex.toCharArray();
byte[] bytes = new byte[hex.length() / 2];
int temp;
for (int i = 0; i < bytes.length; i++) {
temp = digital.indexOf(hex2char[2 * i]) * 16;
temp += digital.indexOf(hex2char[2 * i + 1]);
bytes[i] = (byte) (temp & 0xff);
}
//System.out.println("hex2bin:"+new String(bytes));
return new String(bytes);
} public static void main(String[] args) {
String inputStr = "abcdefghijklmnopqrstuvwxyz_1234567890";
String key = "opensso";// 加密因子
String str = EncryptRC4(inputStr, key);
System.out.println(str);
System.out.println(DecryptRC4(str, key));
}
}

解决方案 »

  1.   

    https://www.clarenceho.net/tech/rc4/rc4.zip用这个试试看String key = "12345";
    RC4 rc4 = new RC4(key);byte[] result = rc4.rc4(data);
      

  2.   

    麻烦你能不能写个完事的DEMO调用程序
      

  3.   

    package net.clarenceho.crypto;import java.util.*;
    import java.security.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;/**
     * This class tests the RC4 implementation of net.clarenceho.crypto.RC4 against
     * the implementation from Cryptix.  To run this test, you will need to install
     * the Cryptix JCE library first.  For details of the Cryptix JCE library,
     * please visit http://www.cryptix.org/products/jce/index.html
     * <p>
     * @author  Clarence Ho
     */
    public class Test {
        
        private static final Random rand = new Random();    
        public Test() {
            
            try {
                Security.addProvider(new cryptix.jce.provider.CryptixCrypto());
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }
                    /**
         * Executes 2 tests.  The first test is to compare the ciphertext output
         * from both net.clarenceho.crypto.RC4 and Cryptix.
         * <br>
         * The second test is to decrypt the ciphertext
         * using net.clarenceho.crypto.RC4 and compare it with
         * the original plaintext.
         */
        public boolean test(byte[] key, byte[] data) {
            try {
                // uses net.clarenceho.crypto.RC4
                RC4 ownRc4 = new RC4(key);
                byte[] result_own = ownRc4.rc4(data);            // uses cryptix
                Cipher c = Cipher.getInstance("RC4", "CryptixCrypto");
                c.init(Cipher.ENCRYPT_MODE, new K("RC4", key));
                byte[] result_cryptix = c.doFinal(data);
                
                // compares two ciphertexts
                if (!Arrays.equals(result_own, result_cryptix)) {
                    return false;
                }
            
                // uses net.clarenceho.crypto.RC4 to decrypt
                ownRc4 = new RC4(key);
                byte[] result_own2 = ownRc4.rc4(result_own);
                
                if (!Arrays.equals(result_own2, data)) {
                    return false;
                }
                
                return true;
                
            } catch (Exception e) {
                System.err.println("");
                e.printStackTrace(System.err);
                return false;
            }
        }    private static boolean genRandomTest() {
            
            int keylength = rand.nextInt(15) + 1;
            byte key[] = new byte[keylength];
            for (int i=0; i < keylength; i++) {
                key[i] = (byte)rand.nextInt(256);
            }
            
            int datalength = rand.nextInt(1500) + 1;
            byte data[] = new byte[datalength];
            for (int i=0; i < datalength; i++) {
                data[i] = (byte)rand.nextInt(256);
            }
            
            System.out.print("key length=" + keylength + ";\tdata length=" + datalength);
            Test test = new Test();
            if (!test.test(key, data)) {
                System.out.println("    \tFailed");
                System.out.println("Problem: key=[" + dumpArray(key) + "]; data=[" + dumpArray(data) + "]");
                return false;
            } else {
                System.out.println("    \tOK");
                return true;
            }
        }
            
        private void bench() {
            try {
                int keylength = 16;
                byte key[] = new byte[keylength];
                for (int i=0; i < keylength; i++) {
                    key[i] = (byte)rand.nextInt(256);
                }
                
                int datalengthMB = 10;
                int datalength = 1024 * 1024 * datalengthMB;
                byte data[] = new byte[datalength];
                for (int i=0; i < datalength; i++) {
                    data[i] = (byte)rand.nextInt(256);
                }
                
                long start = System.currentTimeMillis();
                RC4 rc4 = new RC4(key);
                rc4.rc4(data);
                long end = System.currentTimeMillis();
        
                System.err.println("net.clarenceho.crypto.RC4:");
                System.err.println("Time taken to encrypt/decrypt " + datalengthMB + " MB: " + (end - start) + "ms");
                System.err.println("Speed: " + ((double)1000.0 * datalengthMB / (end - start)) + " MB/s");
                System.err.println("");
        
                // uses cryptix
                start = System.currentTimeMillis();
                Cipher c = Cipher.getInstance("RC4", "CryptixCrypto");
                c.init(Cipher.ENCRYPT_MODE, new K("RC4", key));
                byte[] result_cryptix = c.doFinal(data);
                end = System.currentTimeMillis();
        
                System.err.println("Cryptix:");
                System.err.println("Time taken to encrypt/decrypt " + datalengthMB + " MB: " + (end - start) + "ms");
                System.err.println("Speed: " + ((double)1000.0 * datalengthMB / (end - start)) + " MB/s");
            
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }    }    
        private static String dumpArray(byte[] buf) {
            
            StringBuffer sb = new StringBuffer();
            
            for (int i=0; i < buf.length; i++) {
                if (i > 0) {
                    sb.append(" ");
                }
                
                sb.append(Integer.toString((buf[i] & 0xff) + 0x100, 16).substring(1).toUpperCase());
            }
            
            return sb.toString();
        }
        
        
        public static void main(String args[]) {
            
            System.out.println("Compare ciphertext output between this class and Crypix's implementation...");
            for (int i=0; i < 1000; i++) {
                if (!genRandomTest()) {
                    return;
                }
            }
            
            System.out.println("");
            
            System.out.println("Benching...");
            Test test = new Test();
            test.bench();
        }
        /**
         * This is a Key class from the Cryptix library.  The following
         * is the license statement from Cryptix source file:
         * <p>
         * <pre>
         * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
         * All rights reserved.
         *
         * Use, modification, copying and distribution of this software is subject
         * the terms and conditions of the Cryptix General Licence. You should have
         * received a copy of the Cryptix General Licence along with this library;
         * if not, you can download a copy from http://www.cryptix.org/ .
         * </pre>
         */
        private class K 
        implements Key 
        {
            private final byte[] keyBytes;
            private final String alg;
            
            K(String alg, byte[] keyBytes) 
            {
                this.alg      = alg;
                this.keyBytes = keyBytes;
            }
            
            public String getAlgorithm() { return alg;  }
            public String getFormat()    { return "RAW"; }
            public byte[] getEncoded()   { return (byte[])keyBytes.clone(); }
        }
        
        
        
    }里面都有啊 哥哥
      

  4.   

    cryptix.jce.provider.CryptixCrypto()这个东西不了解,运行不了
    其实我只想要标准的RC4加解密算法,并且需要对加密数据进行16进制转换功能。
      

  5.   

    终于搞定了,真是笨我,闹了半天,原来是字符编码问题,不过还是谢谢你coldanimal