首页 > 其他分享 >发现一肉鸡接口,快来围攻啦~

发现一肉鸡接口,快来围攻啦~

时间:2024-11-11 12:42:30浏览次数:3  
标签:username hash 围攻 int 接口 肉鸡 encryptKey String

系统登录页面,为防止明文传输用户密码,开发者做了安全加固。

服务端暴露一个 loginEncryptKey 的API,用来根据登录名 username 获取 加密秘钥 encryptKey。 前端页面 获取到 encryptKey 后,在请求login登录接口时,会对 用户密码 进行加密传输。

这个 loginEncryptKey 接口的服务端怎么写的呢?下面是完整代码,其中SysLoginModel中定义了 username 属性。程序利用redis缓存,来存储RSA公私钥。

点击查看代码
@PostMapping(value = "/loginEncryptKey")
public Result<String> loginEncryptKey(@RequestBody SysLoginModel sysLoginModel) {
    String cacheKey = LOGIN_ENCRYPT_KEY_CACHE + sysLoginModel.getUserName();
    //缓存获取
    String cache = redisUtil.get(cacheKey, "");
    if ("" != cache) {
        String publicKeyStr = JSON.parseObject(cache).getString("public");
        return Result.successWithMsg(publicKeyStr);
    }

    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    // 初始化密钥对生成器,密钥大小为96-1024位
    keyPairGen.initialize(1024, new SecureRandom());
    // 生成一个密钥对,保存在keyPair中
    KeyPair keyPair = keyPairGen.generateKeyPair();
    // 得到公钥字符串
    String publicKeyString = Base64.encode(keyPair.getPublic().getEncoded());
    // 得到私钥字符串
    String privateKeyString = Base64.encode(keyPair.getPrivate().getEncoded());

    //缓存写入
    JSONObject cacheMap = new JSONObject();
    cacheMap.put("public", publicKeyString);
    cacheMap.put("private", privateKeyString);
    redisUtil.set(cacheKey, cacheMap.toJSONString(), 7 * 24 * 60 * 60);

    return Result.successWithMsg(publicKeyString);
}



在进行API测试中发现,这个接口相当肉鸡!给username传任意值,包括空值,都可以获取到一个秘钥。

显然,这为恶意攻击开辟了绿道。当流量攻击像疯狗一样呼啸而来,就会发生redis缓存穿透,这里虽然不是穿透到数据库,但是不停地生成RSA密钥对,这个程序开销也不小。



我们来看看怎么修复、完善这个接口的生成加密key的逻辑。

首先,接口要校验请求参数,这是对程序员的底线要求。

判空吗?

光判空,显然是不够的。那怎么办?

除了判空,还要判断参数的合法性。对于明显错误的传值,如username是一段1024的大文本,直接pass掉。再如,username不符合系统的用户名设置规则,诸如包含了符号(如果允许@符号,那排除@符号),也直接pass掉。

其次,我们可以判断username在系统里是否存在。不存在,则中止程序,直接响应”非法请求“。当然,这里不能每次都查库,用本地缓存为上。

其次,再来说如何更好地生成、获取encryptKey(加密key)

打开脑洞,直接说重点。---->如果不用redis,岂不妙哉!

统一用一个encryptKey?显然,不够安全。

因此,程序可以预先生成一批 encryptKey。 然后,当接口收到请求时,根据username的哈希值,然后做取模运算,从这批encryptKey里命中一个返回。

随机从这一批encryptKey里直接取一个返回,不香吗?当然不行了,因为后面的login接口里,得用同样的encryptKey来解密用户密码。就是说,login接口也要使用上面的根据username获取encryptKey的方法。

既然涉及到复用,在程序设计上,我们没理由不进行封装。如下是一个示例:

private static int customHash(String username) {
    int hash = 0;
//        hash=username.hashCode(); // 默认的哈希算法
    // 自定义哈希算法,防止被破解
    for (int i = 0; i < username.length(); i++) {
        hash = hash * 17 + username.charAt(i);
    }
    int mod = hash % 10;
    return mod;
}

上面的封装OK吗? - - 不OK(不彻底)!

要封装的,应该是↓

private static String getEncryptKeyByUserName(String username) {
    int hash = 0;
//        hash=username.hashCode(); // 默认的哈希算法
    // 自定义哈希算法,防止被破解
    for (int i = 0; i < username.length(); i++) {
        hash = hash * 17 + username.charAt(i);
    }
    int mod = hash % 10;
    return encryptKeys[mod];
}

有了这种不依赖redis缓存的方案,上面判断username是否在系统里存在的校验,似乎也可以省掉了。

至此,本文结束。本文重点阐释生成、获取加密key的优化办法。接口限流、接口增加签名机制等技术,不在讨论范围内。

标签:username,hash,围攻,int,接口,肉鸡,encryptKey,String
From: https://www.cnblogs.com/buguge/p/18539460

相关文章

  • Java——接口
    一、接口是什么在Java中,接口(Interface)是一种引用数据类型,类似于类,然而它只能包含常量、方法签名和嵌套类型。接口不能包含实例变量或方法的实现(在Java8及之后的版本,可以在接口中定义默认方法和静态方法)。接口主要用于定义类的外部行为,并允许类实现这些行为。二、接口详细介......
  • Qualcomm SA8295P资源解析(一):驱动智能驾驶与车载娱乐的多接口技术先锋
    QualcommSA8295P的核心:多核CPU设计QualcommSA8295P的CPU采用了Kryo695架构,其分成了两种不同配置的核心组,分别是KryoGoldPrime和KryoGold核心。KryoGoldPrime核心带有1MB的L2缓存,最高频率可以达到2.38GHz,而KryoGold核心配备512KB的L2缓存,频率最高为2.09GHz。这......
  • Pyhthon实时行情接口WebSocket接入
    Python做量化,如果是日内策略,需要更实时的行情数据,不然策略滑点太大,容易跑偏结果。之前用行情网站提供的level1行情接口,实测平均更新延迟达到了6秒,超过10只股票并发请求频率过快很容易封IP。后面又尝试了买代理IP来请求,成本太高而且不稳定。在Github上看到一个可转债的Golang高频......
  • stm32以太网接口:MII和RMII
    前言使用stm32和lwip进行网络通信开发时,实现结构如下:而MII和RMII就是stm32与PHY芯片之间的通信接口,类似于I2C、UART等。stm32以太网模块有专用的DMA控制器,通过AHB接口将以太网内核和存储器相连。数据发送时,先将数据从存储器以DMA传输到TXFIFO中进行缓冲,然后由MAC内核......
  • 在vue项目中如何实现权限控制,菜单权限,按钮权限,接口权限,路由权限,操作权限,数据权限如何
    在实际项目开发中,权限管理是一个关键功能,用于控制不同用户对系统资源的访问。权限是对特定资源的访问许可,权限控制的目的是确保用户只能访问到被分配的资源。例如,网站管理员可以对网站数据进行增删改查,而普通用户只能浏览。权限管理的分类根据功能的不同,权限控制可以分为......
  • C++代码优化(二): 区分接口继承和实现继承
    目录1.引言2.接口继承3.实现继承4.如何选择接口继承与实现继承5.完整实例6.总结1.引言        在C++中,区分接口继承和实现继承是一种良好的编程实践,有助于提高代码的可维护性、可读性和可扩展性。接口继承通常指的是从基类继承纯虚函数(purevirtualfunctions......
  • vue通过ollama接口调用开源模型
    先展示下最终效果: 第一步:先安装ollama,并配置对应的开源大模型。安装步骤可以查看上一篇博客:ollama搭建本地ai大模型并应用调用 第二步:需要注意两个配置,页面才可以调用1)OLLAMA_HOST="0.0.0.0:11434"2)若应用部署服务器后想调用,需要配置:OLLAMA_ORIGINS=* 第三步:js流式调......
  • List接口相关问题
    目录1.迭代器Iterator是什么2.Iterator怎么使用?有什么特点?3.如何边遍历边移除Collection中的元素?4.Iterator和ListIterator有什么区别?5.遍历一个List有哪些不同的方式?每种方法的实现原理是什么?Java中List遍历的最佳实践是什么?6.RandomAccess6.1什么是Random......
  • 浅谈 PHP 与手机 APP 开发(API 接口开发)
    一、先简单回答两个问题:1、PHP可以开发客户端?答:不可以,因为PHP是脚本语言,是负责完成B/S架构或C/S架构的S部分,即:服务端的开发。(别去纠结GTK、WinBinder)2、为什么选择PHP作为开发服务端的首选?答:跨平台(可以运行在UNIX、LINUX、WINDOWS、MacOS下)、低消耗(PHP消耗相当少的系统......
  • D61【python 接口自动化学习】- python基础之数据库
    day61数据库定义学习日期:20241107学习目标:MySQL数据库--130:MySQL入门使用学习笔记:在命令提示符内先试用MySQL使用图形化工具操作MySQLDBeaver安装DBeaver连接MySQL总结MySQL安装成功后,可以使用命令提示符查看数据库安装使用图形化工具DBeaver操作MySQL......