服务器这边使用了加密接口,发现接口很多无法解密的数据,进行排查后发现客户端的加密数据是错误的,猜测是秘钥使用错误。
验证后果然是。
和客户端一起排查,发现加密类 实例化一次后,又来了一次传参数的实例化 里面设置了加密类型instance.setDesType(type),导致接口的加密串掉。
private byte[] desKey = desDefaultKey;
private static final String DEFAULT_KEY_ALGORITHM = "DES";
private static CryptoUtils instance;
public static CryptoUtils getInstance(int type) {
if (instance == null) {
synchronized (CryptoUtils.class) {
if (instance == null) {
instance = new CryptoUtils();
}
}
}
instance.setDesType(type);//<<<<<<<********
return instance;
}
public static CryptoUtils getInstance() {
if (instance == null) {
synchronized (CryptoUtils.class) {
if (instance == null) {
instance = new CryptoUtils();
}
}
}
return instance;
}
private void setDesType(int type) {
switch (type) {
case TYPE_ACCOUNT:
desKey = desAccountKey;
break;
case TYPE_DEFAULT:
default:
desKey = desDefaultKey;
break;
}
}
.....
修改的建议,加密类的实例化最好就是一个单一的功能,通过闯入秘钥的方式来解决问题。
修改的是变成
public class CryptoUtils {
private byte[] desDefaultKey = new byte[]{};
private byte[] desAccountKey = new byte[]{};
private byte[] desUploadLogKey = new byte[]{};
private byte[] desKey = desDefaultKey;
private static final String DEFAULT_KEY_ALGORITHM = "DES";
private static CryptoUtils instance;
public static CryptoUtils getInstance(int type) {
if (instance == null) {
synchronized (CryptoUtils.class) {
if (instance == null) {
instance = new CryptoUtils();
}
}
}
instance.setDesType(type);
return instance;
}
public static CryptoUtils getInstance() {
if (instance == null) {
synchronized (CryptoUtils.class) {
if (instance == null) {
instance = new CryptoUtils();
}
}
}
return instance;
}
public static final int TYPE_DEFAULT = 0;
public static final int TYPE_ACCOUNT = 1;
public static final int TYPE_DOWNLOAD = 2;
public static final int TYPE_UPLOAD_LOG = 3;
private void setDesType(int type) {
switch (type) {
case TYPE_ACCOUNT:
desKey = desAccountKey;
break;
case TYPE_UPLOAD_LOG:
desKey = desUploadLogKey;
break;
case TYPE_DEFAULT:
default:
desKey = desDefaultKey;
break;
}
}
public static byte hexToByte(String inHex) {
return (byte) Integer.parseInt(inHex, 16);
}
/**
* byte[] 转16进制
*/
public static String bytesToHexFun(byte[] encryptedData) {
StringBuilder buf = new StringBuilder(encryptedData.length * 2);
// 使用String的format方法进行转换
for (byte b : encryptedData) {
buf.append(String.format("%02x", b & 0xff));
}
return buf.toString();
}
/**
* 加密
*/
public byte[] encrypy(byte[] input) {
}
/**
* 解密
*/
public String decrypt(byte[] input) throws Exception {
return new String(numArray);
}
public static SecretKey getSecretKey(byte[] key) throws Exception {
}
private String toMd5(byte[] bytes) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(bytes);
return toHexString(algorithm.digest(), "");
} catch (NoSuchAlgorithmException e) {
Log.v("toMd5", "toMd5(): " + e);
throw new RuntimeException(e);
}
}
private String toHexString(byte[] bytes, String separator) {
StringBuilder hexString = new StringBuilder();
String hs;
for (byte b : bytes) {
hs = Integer.toHexString(0xFF & b);
if (hs.length() == 1) {
hexString.append("0").append(hs);
} else {
hexString.append(hs);
}
hexString.append(separator);
}
return hexString.toString();
}
}