其它系统给我们这个系统发过来用户名和密码,只能以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));
}
}
但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));
}
}
RC4 rc4 = new RC4(key);byte[] result = rc4.rc4(data);
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(); }
}
}里面都有啊 哥哥
其实我只想要标准的RC4加解密算法,并且需要对加密数据进行16进制转换功能。