alibaba / spring-cloud-alibaba

Spring Cloud Alibaba provides a one-stop solution for application development for the distributed solutions of Alibaba middleware.
https://sca.aliyun.com
Apache License 2.0
27.85k stars 8.31k forks source link

NacosRefreshHistory uses BigInteger's toString(16) method to calculate md5. #3853

Open photowey opened 1 week ago

photowey commented 1 week ago

NacosRefreshHistory 直接采用 BigInteger 的 toString(16) 方法来计算 MD5,是否有计算结果长度不足32位数的风险? NacosRefreshHistory uses BigInteger's toString(16) method to calculate md5. Is there a risk that the calculated result will be less than 32 digits long?

Which Component Nacos 配置中心 Nacos(spring-cloud-starter-alibaba-nacos-config) 版本: 2023.x version: 2023.x

Describe what problem you have encountered 直接采用 BigInteger#toString(16) 计算 md5 NacosRefreshHistory uses BigInteger's toString(16) method to calculate md5.

// com.alibaba.cloud.nacos.refresh.NacosRefreshHistory#md5
private String md5(String data) {
    if (StringUtils.isEmpty(data)) {
        return null;
    }
    if (null == md) {
        try {
            md = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException ignored) {
            return "unable to get md5";
        }
    }

   // toString(16) ?
    return new BigInteger(1, md.digest(data.getBytes(StandardCharsets.UTF_8)))
        .toString(16);
}

Describe what information you have read 直接阅读源码发现的。 I have read the source code of Nacos(spring-cloud-starter-alibaba-nacos-config).

ruansheng8 commented 4 days ago

BigInteger.toString(16) 中的 16 是表示 16 进制,并不是字符串的长度。

photowey commented 2 days ago

Test case:

    @Test
    void testMD5Length() {
        Random random = new Random();
        for (int i = 0; i < 10_000; i++) {
            int randomLength = random.nextInt(100);
            // @see https://github.com/aventrix/jnanoid
            String nanoid = NanoIdUtils.randomNanoId(NanoIdUtils.DEFAULT_NUMBER_GENERATOR, NanoIdUtils.DEFAULT_ALPHABET, randomLength);
            String md5 = md5(nanoid);
            if (md5.length() < 32) {
                System.out.println(nanoid);
                System.out.println(md5);
                System.out.println(md5.length());
                break;
            }
        }
    }

// Output:
// pIzSCJjkj
// d5a0763f00d07ce414ea6ffc46d26a6
// 31

// Expect: 
// 0 + d5a0763f00d07ce414ea6ffc46d26a6
// 0d5a0763f00d07ce414ea6ffc46d26a6