在工作中,我们常常会遇到这样的情况,我们需要经一个我们敏感的数据从一个地方传递到另一个地方,但是我们又不想这些数据在中途传输时被截获发现,于是我们想到了将这些数据进行加密传输,然后再接收地使用我们知道的规则进行反向解析得到原始数据。今天我们来讲一种加密算法,那就是异或加密算法。由于工作安全性的要求,我们队异或算法进行了一点升级,如果有类似的需求,可以借鉴此文得到一点灵感。
实际的需求:
1. 我们需要将一个数据从一个地方传递到另一个地方,这个数据时关于用户的敏感数据,不想被第三方截获发现使用;
2. 我们希望接收方能够根据接收的数据反向直接解析出原数据,而不需要调用第三方接口查询接收到数据的原始数据;
3. 我们希望加密后的长度能够一致;
现在的加密算法很多,算法太过负责精妙啦,重点是加密后的字符串含有一些特殊字符,需要在HTTP请求中进行特殊编码处理,因此在工作中,我放弃了使用那些算法,转而选择了比较简单的异或算法,只是在原有异或算法的基础上进行了部分特殊化处理,以增强加密后数据的不可解析性。
具体加密过程:手机号前加上随机三位数字,手机号后加上随机三位数字,然后将所得字符串循环左移八位,再根据异或运算对得到的数字进行异或运算并转换成15位十六进制字符串,最后在15位字符串前加上2位随机十六进制字符和1位用于标识采用哪种加密key的数字标识。
异或算法KEY(18位数字)使用三组加密秘钥key1,key2,key3(支持可配置)。
在加密过程中随机生成一位0-3的随机数N确定使用哪个KEY,规则如下:
0: key1 189076573222322987
N 1 : key2 889237829273747382
2: key3 283847383829237483
示例代码如下(代码中的KEYS可以在配置文件中进行配置):
<span style="font-size:18px;"><span style="font-size:18px;">public final class UidGenerator {
private static final Random RANDOM = new Random(System.currentTimeMillis());
public static final String generateUidFromCaller(String caller) {
StringBuilder sb = new StringBuilder();
int randomnumber = RANDOM.nextInt(3);
sb.append(generateRandStr(3, 10));
sb.append(caller);
sb.append(generateRandStr(3, 10));
String preTokenid = sb.substring(8, sb.length()) + sb.substring(0, 8);
BigInteger t1 = new BigInteger(preTokenid);
t1 = t1.xor(selectKeyByRandomNumer(randomnumber));
sb.setLength(0);
Long result = t1.longValue();
String temp = Long.toHexString(result);
sb.append(temp);
while (sb.length() < 15) {// 18位的数字转换成十六进制最多15位
sb.insert(0, '0');
}
sb.insert(0,generateRandStr(2, 10));
sb.insert(0,randomnumber);
return sb.toString();
}
public static final String getCallerFromUid(String tokenid) {
// 取出插入标识哪个加密密钥的随机数randomnumber
int randomnumber = TryParser.parseInt(tokenid.substring(2, 3), -1);
if (randomnumber == -1) {
return null;
}
StringBuilder sb = new StringBuilder(tokenid);
sb.delete(0, 3);
Long tokenidLong = Long.parseLong(sb.toString(), 16);
BigInteger t1 = new BigInteger(tokenidLong + "");
t1 = t1.xor(selectKeyByRandomNumer(randomnumber));
String result = t1.longValue() + "";
if (StringUtils.length(result) >= 8) {
sb.setLength(0);
sb.append(result.substring(result.length() - 8, result.length()));
sb.append(result.substring(0, result.length() - 8));
sb.delete(0, 3);
sb.delete(sb.length() - 3, sb.length());
String caller = sb.toString();
if (isValidCaller(caller)) {
return caller;
}
}
return null;
}
private static BigInteger selectKeyByRandomNumer(int n) {
return KEYS[n % 3];
}
public static String generateRandStr(int length, int max) {
StringBuilder result = new StringBuilder();
if (length > 0) {
while (length > 0) {
result.append(RANDOM.nextInt(max));
length--;
}
}
return result.toString();
}
}</span>
</span>
希望通过此文,对于一些想加密处理数据传输的人来说有一定帮助或者给你们一些灵感,那就达到我的目的了。