一个单例的错误用法引发的思考

博客讲述了在服务器端遇到加密接口解密失败的问题,经过排查发现是客户端加密类实例化时设置加密类型的错误导致。文中详细分析了问题原因,并提出了修改建议,将加密类实例化改为仅接受秘钥参数,以解决不同场景下的加密需求。同时,提供了加密和解密的相关方法实现。
摘要由CSDN通过智能技术生成

服务器这边使用了加密接口,发现接口很多无法解密的数据,进行排查后发现客户端的加密数据是错误的,猜测是秘钥使用错误。

验证后果然是。

和客户端一起排查,发现加密类 实例化一次后,又来了一次传参数的实例化 里面设置了加密类型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();
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值