public static function coverSensitiveValues(array $data, array $keys = [])
    {
        if (empty($keys)) {
            $keys = self::$sensitiveDefaultKeys;
        }
        
        $clean = [];
        foreach ($keys as $key) {
            $kw = strtolower($key);
            foreach ($data as $k => $v) {
                if (is_array($v)) {
                    $clean[$k] = static::coverSensitiveValues($v, $keys);
                } elseif (is_scalar($v) && ($kw == strtolower($k) || StringHelper::startsWith(strtolower($k), $kw))) {
                    $v = str_repeat("*", strlen($v));
                    $clean[$k] = $v;
                }
            }
        }
        
        // the later overrides the former
        return array_replace($data, $clean);
    }