V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dzdh
V2EX  ›  SSL

API 接口已经有 HTTPS 的前提下,为什么还需要签名机制?

  •  4
     
  •   dzdh · 2021-04-12 19:48:35 +08:00 · 13742 次点击
    这是一个创建于 1322 天前的主题,其中的信息可能已经有所发展或是发生改变。

    注意场景:

    • 服务端对服务端的接口,不是客户端对服务端的接口
    • 防止中间人可以 PINNED Pub Key,因此中间人攻击不在考虑范围内
    • 极端条件可以使用客户端证书

    综合以上三点。为什么在 Https 的保护下,还要额外做签名验证?

    主要疑问,如 stripe 的退款接口

    curl https://api.stripe.com/v1/refunds -u "$密钥:" -d charge=$charge_id
    

    就可以发起一笔订单的退款或者扣款。按照某些论述的话,没有签名的 Stripe 岂不是非常危险?

    第 1 条附言  ·  2021-04-13 08:51:25 +08:00

    签名指的是

    data = { "a":"1", "b":2}
    
    data = sort(data) # 按照一定规则对data进行排序
    
    signString = getSignString(data) # 按照一定规则将数据拼成一个字符串
    
    sign = sign(signString) #按照指定算法如md5/shaX等计算hash得到最终的『签名』
    
    data.sign = sign # 最终请求数据
    
    
    第 2 条附言  ·  2021-04-13 09:01:22 +08:00

    初步总结:

    在使用HTTPS的前提下,已经保证了足够的安全性。完全没有必要再额外做一套『签名机制』。

    防重放攻击,依靠的是API接口本身的逻辑设计,如下场景,订单相关:

    // 根据KEY找到user
    $user = Db::table('key_user')->where('key', $request->get('key'))->find();
    // 验证key、user是否合法、有权限、balabalabala
    // 验证key、user的请求频率
    // 如上两步都可以作为中间件全局统一处理
    
    // 查: 无所谓、随便查,无所谓是否重放攻击
    return new Response(balabalabala)
    // 改: 下单、关闭、结算等balabala
    // 下单:订单是否已经存在,存在报错已存在不存在入库
    // 关闭:验证订单状态,能关闭就关闭,不能关闭报错
    

    如上PHP代码逻辑完全可以有效防止『重放』带来的『损失』,而且还可以加入一个timestamp参数,可以有效防止TCP数据包重放

    第 3 条附言  ·  2021-04-13 15:48:30 +08:00
    第二次总结:

    所有人的质疑是否代表着 Stripe 和 Paypal 现在是极度危险状态?
    第 4 条附言  ·  2021-04-14 00:00:29 +08:00

    第三次总结:

    公开API的接口设计,在有HTTPS的前提下,签名负数『非必要』可以不使用签名。

    要注意的是:

    1. CDN不可信(事实是如果你要使用CDN你就只能被动选择相信)
    2. CDN到源站链路不安全(需要HTTPS回源)
    第 5 条附言  ·  2021-04-14 03:45:11 +08:00

    20210414-0320总结:

    收集罗列了一些国内外的一些大型API服务使用单纯的HTTPS而没有『签名』参与的厂商和认证模式。

    国外已知服务

    • Github (Http Authentication 或 OAuth 二选一)
    • Stripe (Http Authentication)
    • Paypal (access_token)
    • Facebook(Server端调用系列API)+ access_token
    • Twitter (Server端调用系列API)+ access_token
    • Instagram
    • Google Cloud API (URL传递KEY) 国内已知服务
    • 华为云(Token认证模式)

    总结: 国内还是偏向一定要有『签名』的多,不知为何。

    第 6 条附言  ·  2021-04-15 19:03:51 +08:00

    最终总结

    https+签名 ¹ 会『更』安全。

    但是,https自身的安全程度足够,没有再额外增加签名 ¹ 机制的必要性。

    安全问题主要出在客户端自身网络环境安全。

    结贴

    1: 签名指的是类似 md5( sortedString + key ) 的附加请求参数

    248 条回复    2021-04-14 18:54:11 +08:00
    1  2  3  
    screen
        1
    screen  
       2021-04-12 19:52:18 +08:00 via iPhone   ❤️ 4
    大多数攻击来自客户端的截取、伪造而非信息传递中
    xmumiffy
        2
    xmumiffy  
       2021-04-12 19:53:11 +08:00 via Android   ❤️ 4
    是没必要
    dzdh
        3
    dzdh  
    OP
       2021-04-12 19:53:51 +08:00
    @screen 如果 SSLPinning 无效的话,那客户端用『签名』也一样能截取啊
    dzdh
        4
    dzdh  
    OP
       2021-04-12 19:55:16 +08:00
    @xmumiffy 国内大厂是出于什么样的考量呢?
    iyaozhen
        5
    iyaozhen  
       2021-04-12 19:56:22 +08:00   ❤️ 1
    签名我记得是两边约定一个 token,把参数和 token 签一下,更安全

    一般用在开放接口上吧,就是接口参数大家都知道,你别的地方不小心泄露参数了,就有风险
    xmumiffy
        6
    xmumiffy  
       2021-04-12 19:56:28 +08:00 via Android
    @dzdh 十年前 http 年代我们是这么做的 现在也没必要改
    des
        7
    des  
       2021-04-12 20:04:23 +08:00   ❤️ 1
    我猜测可能是这几个原因
    一是方便用 http,http 也方便调试
    二是即使是服务端对服务端,走的是统一的网关,不想再搞一个域名
    三是不少人对 https 认识不那么够,不会搞证书认证,毕竟资料也少,相对于签名
    dzdh
        8
    dzdh  
    OP
       2021-04-12 20:08:58 +08:00
    @des

    1 理解
    2 网关统一 HTTPS 不是更简单了么都不用再配置啥
    3 emmmm 理解
    momocraft
        9
    momocraft  
       2021-04-12 20:16:58 +08:00   ❤️ 2
    签名虽然现在看觉得傻 十年前不失为一个 http 下能加密+防重放攻击的方案

    另外市场地位不一样 要是 stripe 敢像企鹅这样一个 QR 码写出不到十种 API 可能活不到上市
    akira
        10
    akira  
       2021-04-12 20:18:01 +08:00   ❤️ 2
    你要这么说的话,服务端对服务端 http 就够了,ssl 都不需要上
    ihipop
        11
    ihipop  
       2021-04-12 20:22:51 +08:00 via Android   ❤️ 1
    现在很多方案是前端 HTTPS 网关后面业务系统是 HTTP,如果做使用客户端做 SSL 认证,整个系统都需要要改造,不可能业务系统身份认证全做网关上吧? SSL 只 pin 服务端的证书没法验证客户身份,签名不仅仅可以防篡改,还能客户做身份认证
    dzdh
        12
    dzdh  
    OP
       2021-04-12 20:33:02 +08:00
    @ihipop 还好吧,客户端证书在网关直接验证好的,到后面的 HTTP 业务的时候直接带着 https_s|c_xx 的 header 头的哇而且还伪造不了
    dzdh
        13
    dzdh  
    OP
       2021-04-12 20:33:21 +08:00
    @ihipop 不是老系统改造,是新系统
    wooyuntest
        14
    wooyuntest  
       2021-04-12 20:56:35 +08:00   ❤️ 1
    加大直接构造数据向接口发请求的难度(还得逆向 app 拿到签名算法)
    dzdh
        15
    dzdh  
    OP
       2021-04-12 20:58:55 +08:00
    @wooyuntest 找密钥吧。这是客户端场景了,即便如此,仅使用 HTTPS 直接传递 ukey 的话也得逆向啊。
    HOOK 方案的话无论任何方案都没辙吧。
    kejialiu
        16
    kejialiu  
       2021-04-12 21:57:13 +08:00 via Android   ❤️ 1
    签名是一次性的,只针对这个请求,就算被截获了也伤害不大。密钥不管什么原因被泄露了,后续所有请求都可以伪造,所以能不暴露就不暴露,哪怕是加密通道
    dzdh
        17
    dzdh  
    OP
       2021-04-12 23:05:50 +08:00
    @kejialiu

    一次性的根本原因是因为有 nonce 。以此为目的达到防 Replay Attack 。

    但是究其根本,HTTPS 本身被抓到已有也是个无法篡改的普通 TCP 数据包。重放攻击也只能将这个数据包无数次发送给对方服务器。也就是说,只要在普通的请求参数中加入任意一个具备 nonce 特性的参数如 timestamp,那这个数据包依然可以被直接拦截。

    同时,如果说 HTTPS 不用构造直接可以无限次任意请求的话,签名模式难道就不是吗?
    dzdh
        18
    dzdh  
    OP
       2021-04-12 23:11:30 +08:00
    @kejialiu

    即便没有 nonce 。如 http://domain/path?order_id=x&sign=n 。是的没错,这个请求无法被篡改,但是我依然可以肆无忌惮的发起查询啊。

    而且肯定是要有一个『某 ID 』的参数吧?如商户 ID 、用户 ID 等标记唯一应用的参数吧。那也就是说,只是某一个『用户』或『应用』能构造针对特性对象『 order_id=x 』的请求。

    那相应的,HTTPS 的话直接作为 Authentication Header 参数放进来一样的哇。
    Vegetable
        19
    Vegetable  
       2021-04-13 00:09:10 +08:00   ❤️ 1
    这个有历史的惯性原因吧,大家都有签名,我这没签名显得不安全。

    另一个可能是,对于在网络请求中传递密钥的恐惧?我这两天正在设计一个 s2s 接口,也非常纠结到底要不要做签名
    ch2
        20
    ch2  
       2021-04-13 01:00:47 +08:00 via iPhone   ❤️ 1
    过滤掉不会签名的傻子,仅此而已
    crab
        21
    crab  
       2021-04-13 03:29:22 +08:00   ❤️ 1
    防中间人也要防客户
    skull
        22
    skull  
       2021-04-13 06:42:41 +08:00 via Android   ❤️ 2
    瞎回答一下,服务端对服务端是理论场景,放出去的 api 不敢保证对方也是服务端
    ferock
        23
    ferock  
       2021-04-13 07:20:16 +08:00 via iPhone   ❤️ 1
    防御的场景不同
    wanguorui123
        24
    wanguorui123  
       2021-04-13 08:17:28 +08:00 via iPhone   ❤️ 1
    AppKey 安全的前提下,签名的过期时间戳有一定防止重放的功能,HTTP 下可以额外防止数据篡改,HTTPS 下除了对过期时间的验证好像没什么用
    dzdh
        25
    dzdh  
    OP
       2021-04-13 08:38:17 +08:00
    @Vegetable 签名机制完全没必要,安全及重放等攻击的防止是靠接口逻辑设计的,不是靠签名的。
    dzdh
        26
    dzdh  
    OP
       2021-04-13 08:38:41 +08:00
    @crab Pinned Pub Key 还怎么中间人呢?防止客户的什么呢?
    dzdh
        27
    dzdh  
    OP
       2021-04-13 08:39:13 +08:00
    @skull 对方不是服务端能怎样呢?
    dzdh
        28
    dzdh  
    OP
       2021-04-13 08:39:34 +08:00
    @ferock 比如?
    dzdh
        29
    dzdh  
    OP
       2021-04-13 08:41:27 +08:00
    @wanguorui123

    参见 18 楼。

    如 http://domain/path?order_id=x&sign=n 。是的没错,这个请求无法被篡改。

    我可以直接不停的直接请求,这就是重放攻击对吧?那就单单是『签名』是怎么防止重放攻击的呢?难道不是 API 的露酒设计来检测 order_id 的请求次数么?或者 sign 的请求次数么?无论是否是签名都需要做这一步啊?
    dzdh
        30
    dzdh  
    OP
       2021-04-13 08:42:04 +08:00
    @dzdh 漏酒 => 逻辑。

    我一直怀疑我的键盘坏了 ...
    ferock
        31
    ferock  
       2021-04-13 09:14:26 +08:00 via iPhone
    @dzdh #28

    楼上不是很多人都说了吗?
    ssl 防御的是中间人攻击
    而签名是防御:非授权客户的额外请求

    不是一个场景
    wanguorui123
        32
    wanguorui123  
       2021-04-13 09:17:21 +08:00
    @dzdh xxx&timestarp=xxx,timestarp 就是时间戳,通过判断过期时间和上次请求的时间戳过滤请求
    yukiww233
        33
    yukiww233  
       2021-04-13 09:28:58 +08:00
    1 签名会把时间戳签进去;
    2 签名不能完全避免, 只是增加了一层破解客户端的难度
    3 没看懂你那段"业务逻辑"是怎么防止重放的, key 是 server 返回的, 那直接重放 server 返回 key 的请求呢?
    pkoukk
        34
    pkoukk  
       2021-04-13 09:46:47 +08:00
    提高伪造消息的门槛啊。
    作为码农肯定都干过 F12 查 api 地址参数,然后假冒浏览器调用 api 的行为。
    有了签名就得逆向代码找到签名逻辑,如果没有签名就直接拿来用了
    dzdh
        35
    dzdh  
    OP
       2021-04-13 09:48:05 +08:00
    @yukiww233 33
    @wanguorui123 32
    我接受请求啊,因为你的 KEY 是合法的啊( stripe 的 user)。

    但是针对某一个资源的操作如 x_id=N,只要我接口保持幂等,无所谓重放不重放吧?对实际业务 0 损失啊?即便有签名,也只是根据 timestamp 和当前服务器时间的差值决定是否拒绝请求,但是请求依然进来了啊。
    dzdh
        36
    dzdh  
    OP
       2021-04-13 09:48:50 +08:00
    @ferock

    这个『授权』是怎么定义呢?签名怎么体现『授权』呢?客户端证书是否也能实现呢?
    dzdh
        37
    dzdh  
    OP
       2021-04-13 09:50:00 +08:00
    @pkoukk
    注意场景 Server 端到 Server 端。没有浏览器。
    即便有客户端的场景,哪个浏览器端的接口设计是有签名的请赐教
    dzdh
        38
    dzdh  
    OP
       2021-04-13 09:51:43 +08:00
    @yukiww233 32

    key 是 被调用方 分配 /颁发给 调用方,或调用方主动在被调用方处登记注册的。如帐号密码
    wanguorui123
        39
    wanguorui123  
       2021-04-13 09:52:23 +08:00
    @dzdh 1 、有些时候需要防止重复下单,通过 timestarp 验证是否和上次相同来避免、2 、有些时候防止文件被盗链,这时候通过 timestarp 的过期时间来验证是否是过期资源,防止迅雷等工具盗刷流量
    dzdh
        40
    dzdh  
    OP
       2021-04-13 09:57:02 +08:00
    @wanguorui123 39
    理解。但是:

    > 注意场景是 Server To Server

    1. API 的接口设计的逻辑是否可以要求下单的时候带上一个发起方的 ID 呢?这个 ID 不就是个 nonce 么?根据这个 ID 也可以防止某个内部服务重复下单啊(注意场景是 Server 端到 Server 端,如 stripe 、paypal 、支付宝、微信的预下单接口)

    2. 是否可以直接生成一个加密 token 在 token 里直接绑定 ip 、时间戳,然后这个 token 一次有效呢?只能由 openssl 解密(是的,没有仅仅只依靠 HTTPS )

    我指的签名仅仅指的是:按照规则排序然后拼字符串使用 shaX/mdX 的形式
    wanguorui123
        41
    wanguorui123  
       2021-04-13 10:01:12 +08:00
    @dzdh 其实不考虑特殊情况,携带 Token 或者 Session 加 HTTPS 已经足够安全了
    wy315700
        42
    wy315700  
       2021-04-13 10:09:58 +08:00
    其实写程序的时候,你永远要考虑对面那端的傻逼行为,要在对方傻逼的时候依然尽可能的保证程序接口可用性。
    楼主这么想一想,就知道为啥一些接口会有奇奇怪怪的设计了。


    你可能觉得 server to server 加上 标准化的 HTTPS 是一个安全的协议。。

    但是如果对面不是 server 呢,直接把接口写到客户端了呢,有见过直接客户端直接连接远程 MySQL 的程序。
    再或者是,有人嫌麻烦,HTTPS 关闭了证书验证呢,据了解这么做的不在少数。
    keyfunc
        43
    keyfunc  
       2021-04-13 10:10:08 +08:00
    首先,你不能保证 ssl 隧道肯定安全,密钥泄漏,使用了不安全的密码套件等都会导致 ssl 存在安全漏洞。
    签名挑战机制足够简单,越简单的方法越安全。
    newmlp
        44
    newmlp  
       2021-04-13 10:29:36 +08:00
    tls 只能保证端和端之间是安全的,如果客户端不安全你用 https 没啥用,加个自己的签名可以增加反编译的难度
    crab
        45
    crab  
       2021-04-13 10:33:32 +08:00
    @dzdh 我是说 ssl/tls 防中间人,多个签名防使用者客户。
    wentx
        46
    wentx  
       2021-04-13 11:08:28 +08:00
    这个应该是取决于对安全性的要求,像 stripe 这用了 HTTPS + 请求 Sign 的 API 应该就是双重保障,毕竟都是跟钱相关的,如果某个用户的本地被加了一层类似于 Charles 的 HTTPS 代理,那它还可以通过 API 签名来防一手的.
    David1119
        47
    David1119  
       2021-04-13 11:11:50 +08:00
    主要不是为了安全,是为了反爬好吗,防止用户把数据都爬走,大部分都是 so 加密算法,增加客户端破解难度
    timedivision
        48
    timedivision  
       2021-04-13 11:14:15 +08:00
    安全没有绝对的,为了更安全,谁都愿意多加几道锁就好比我把钱放保险柜里,我保险柜不还得放家里吗?难道我把保险柜放外面?
    kejialiu
        49
    kejialiu  
       2021-04-13 12:10:36 +08:00
    @dzdh 一个设计合理的请求签名算法中,所有有含义的请求参数都是被签名的对象,任何参数的修改都会导致签名失效,所以被拦截了也就只能重放那一个特定请求而已。更别说还有时间戳限制有效时间。总体原则就是,如果拦截不可避免,也要把损失降到最小
    borisz
        50
    borisz  
       2021-04-13 12:19:02 +08:00
    防抵赖
    kejialiu
        51
    kejialiu  
       2021-04-13 12:23:49 +08:00 via Android
    安全从来都是相对的,一般我们是可以认为 https 是可以防中间人的,但这也是有前提的:
    - https 服务端的密钥是怎么管理的,都有谁经手了,不小心泄露了呢?
    - 浏览器这样的客户端是否可信任呢?里面会不会装了莫名其妙的插件钩子呢?
    - 签发 https 证书的 CA 是不是足够可信任呢?

    根据你的应用的敏感级别,这些可能都是需要考虑的因素。比如 Google 的安全原则是所谓 n+1,意思就是你总是要多做一层防护,让不明真相的程序员在做错了 n 件事的情况下仍能保证安全。
    borisz
        52
    borisz  
       2021-04-13 12:27:38 +08:00
    https 只能表示传输的数据时正确的, 但是能保证传输的数据对于系统时无害的,

    例如平台内部用户伪造支付请求, 或者内部大量无效请求, 测试需求发送到业务服务器.
    Telegram
        53
    Telegram  
       2021-04-13 12:32:16 +08:00   ❤️ 1
    这是概念混淆啊,照你意思是用了 https,用户就不需要账号密码了?
    no1xsyzy
        54
    no1xsyzy  
       2021-04-13 12:54:38 +08:00
    SSL/TLS 不能确定对方是否对你的证书进行了验证。
    双边证书使用相对麻烦。
    然后还有遗留问题和习惯问题。
    VHacker1989
        55
    VHacker1989  
       2021-04-13 13:01:54 +08:00
    任何客户端做的校验都是多此一举,逆向,动态调试,xposed hook 都能破解和获得密钥,因为客户端完全掌握在用户手里
    Marinaaaa
        56
    Marinaaaa  
       2021-04-13 13:21:18 +08:00
    给不怀好意的人增加更多破解成本。如
    Marinaaaa
        57
    Marinaaaa  
       2021-04-13 13:23:19 +08:00
    如果是服务端对服务端,且都是内部系统,内网访问的话,感觉没太必要。如果非内网访问的话可能还是有点风险吧
    hxndg
        58
    hxndg  
       2021-04-13 13:31:29 +08:00   ❤️ 1
    只能说明两个现象:
    1 很多人对于 TLS 的理解是一知半解的,TLS 本身是非常灵活的,可以根据需求变更 auth/enc/verify 等功能,好多人只知道个 enc 就完了,建议重新研读下 RFC,上面的回复里面有明显的错误。
    2 TLS 层安全开发做的不到位,很多的功能原本是明文的,为了一些安全的功能采用了打补丁的方式,而 TLS 加入以后处于兼容性功能或其他方面考虑没能去掉这些补丁。 毕竟国内做业务的和我们这些做基础服务的关注的点不同。
    walpurgis
        59
    walpurgis  
       2021-04-13 13:31:33 +08:00 via Android
    @Telegram 因为传输层可以保证安全的话,密码可以直接明文传了,不需要将密码再套一层 HMAC 了
    3dwelcome
        60
    3dwelcome  
       2021-04-13 13:36:04 +08:00
    "Pinned Pub Key 还怎么中间人呢?防止客户的什么呢?"

    能做到这种验证毕竟是少数,大部分服务器就校验了一下对方 CERT 有效性,因为 CERT 会过期,客户定期会换,你又没办法一直保证服务器存有对方最新的 KEY 和 CERT 来校验。

    而且我看所有有钱有关的网络支付,都带签名。

    这其实和数据库是不是存用户明文密码是同一个问题:反正用户又看不到服务器上具体有什么,不存 hash,直接存明文是不是一样的?(学一下楼主额外描述:服务器不可能被攻破,因此黑客攻击不在考虑范围内)
    hxndg
        61
    hxndg  
       2021-04-13 13:36:09 +08:00
    @Marinaaaa 内网访问没有必要这个目前已经被认为是错误的了。

    @no1xsyzy 你的证书是谁的证书? TLS server 端还是 client 端?

    @Telegram 用户名和密码是保护什么?签名是保护什么?
    @borisz 所以签名能保证数据对系统无害?
    hxndg
        62
    hxndg  
       2021-04-13 13:40:50 +08:00
    @3dwelcome
    那东西叫做公钥钉扎,防备中间人,已经废除了。
    此外
    签名和数据库存储明文密码根本不是一个概念,每个步骤都是有其基本目的的,签名是用来防抵赖,抗修改+重放的
    数据库不能存储明文用 hash 是对抗内部攻击,泄漏的
    3dwelcome
        63
    3dwelcome  
       2021-04-13 13:54:41 +08:00   ❤️ 1
    @hxndg
    "那东西叫做公钥钉扎,防备中间人,已经废除了。"
    不不,楼主说的是 Server to Server 上的 PubKey 验证,就是直接在 TLS 握手阶段,读取证书里的 pubkey,看是不是和数据库里的一致,服务器要额外写一些入侵式代码。

    你说的废除,只是 chrome 浏览器里定下的规范。楼主这里没有浏览器的参与。
    xuanbg
        64
    xuanbg  
       2021-04-13 13:56:36 +08:00
    SSL 是可以保证数据传输的安全,但也仅仅是保证数据传输过程安全而已。数据在传输前是不是伪造的?这个 SSL 可没法保证。
    hxndg
        65
    hxndg  
       2021-04-13 14:06:56 +08:00
    @3dwelcome

    1 首先公钥钉扎,或者说公钥固定( whatever )不单纯针对浏览器,任何涉及到 TLS 的都会做,我们实现了钉扎,但是国内没人用,最后没进正式 build,代码被废除了。国内没有一个运营商采用这东西,几大银行更是提都不提。
    2 chrome 废除了这个确实,这点我确实说错了。
    AlisaDestiny
        66
    AlisaDestiny  
       2021-04-13 14:18:29 +08:00   ❤️ 1
    其实这就像登录密码和支付密码,登录密码只能确定付款方身份是你,但这并不代表这次的支付请求是由你本人发起(比如你室友趁你睡觉的时候拿你手机给自己转账),所以需要你输入支付密码确认。
    dzdh
        67
    dzdh  
    OP
       2021-04-13 15:19:23 +08:00
    @newmlp 如果客户端不安全『签名机制』也没啥用,这个理由不成立
    dzdh
        68
    dzdh  
    OP
       2021-04-13 15:20:30 +08:00
    @AlisaDestiny 这个场景『签名机制』也没用,因为如果『支付密码』你泄露了呢?安全上两个方案一样的,甚至不如 HTTPS
    dzdh
        69
    dzdh  
    OP
       2021-04-13 15:22:02 +08:00
    @xuanbg HTTPS 能够保证传输安全已经足够了,真正的 API 请求安全(身份鉴别)不是依靠其传递的参数实现的吗?直接 HTTPS+HTTP Authenctication 一样的啊?
    dzdh
        70
    dzdh  
    OP
       2021-04-13 15:23:09 +08:00
    @3dwelcome 63

    对的,只是 Chrome 废除而已,无论是 Server 端还是 Client 端,只要你验证,依然是可以进行服务端身份鉴别的啊
    dzdh
        71
    dzdh  
    OP
       2021-04-13 15:24:14 +08:00
    @Telegram
    几楼或者哪句话有『不需要账号密码』的意思,请指出。
    dzdh
        72
    dzdh  
    OP
       2021-04-13 15:25:25 +08:00
    @keyfunc 43

    密钥泄露和签名所用的密钥泄露是同等效的,那同样也不能证明『签名机制』的安全。该理由不成立
    dzdh
        73
    dzdh  
    OP
       2021-04-13 15:26:28 +08:00
    @newmlp 44

    同理可证明,如果客户端不安全(如『签名模式』的密钥摆在明面上),那『签名机制』远没有『 HTTPS 』安全。该理由不成立。
    dzdh
        74
    dzdh  
    OP
       2021-04-13 15:28:10 +08:00
    @wentx 46

    Charles 是依靠『中间人』来进行抓包的。

    其次,如果真的使用 Charles,那是不是就意味着其已经控制了『物理机』?在控制『物理机』的前提下还有什么安全方案是可以保证『全安』的吗? 并不能证明 HTTPS 环境下,签名模式的『必要性』
    dzdh
        75
    dzdh  
    OP
       2021-04-13 15:29:39 +08:00
    @David1119 47

    接口设计要求 CleintID,爬虫场景完全可以屏蔽 ClientID 。

    其次,标题是 Server 端到 Server 端。即便是用户不小心暴露 API,依然可以屏蔽 ClientID,中断爬虫行为。该理由不成立。
    dzdh
        76
    dzdh  
    OP
       2021-04-13 15:30:35 +08:00
    @timedivision 48

    请阐明就目前技术手段方案中,HTTPS 前提下,签名模式的『必要性』
    dzdh
        77
    dzdh  
    OP
       2021-04-13 15:35:20 +08:00
    @kejialiu 49

    比如?

    比如下单场景,可以要求调用方生成唯一『请求号』,在接口设计逻辑上可以进行规避。

    有没有什么场景是『无法』进行规避的?
    dzdh
        78
    dzdh  
    OP
       2021-04-13 15:39:38 +08:00
    @kejialiu 51

    HTTPS 防止中间人有 SSLPinning 的方案,足矣无限接近 100%的保障安全(请提出反对意见)

    - https 服务端的密钥是怎么管理的,都有谁经手了,不小心泄露了呢?
    回:签名模式的密钥怎么管理的?都谁经手了,不小心泄露了呢?

    - 浏览器这样的客户端是否可信任呢?里面会不会装了莫名其妙的插件钩子呢?
    回:Server 端到 Server 端,签名模式就能规避『莫名其妙』的钩子是吗?

    - 签发 https 证书的 CA 是不是足够可信任呢?
    回:本地指定 CA 文件验证


    根据你的应用的敏感级别,这些可能都是需要考虑的因素。比如 Google 的安全原则是所谓 n+1,意思就是你总是要多做一层防护,让不明真相的程序员在做错了 n 件事的情况下仍能保证安全。
    回:所以是 HTTPS 足矣保证安全,仅仅只是为了多加一层兜底手段,对吗?
    dzdh
        79
    dzdh  
    OP
       2021-04-13 15:40:57 +08:00
    @borisz 52

    所以 paypal 和 stripe 两个平台是极度危险的是吗?
    dzdh
        80
    dzdh  
    OP
       2021-04-13 15:42:17 +08:00
    @no1xsyzy 54

    - SSL/TLS 不能确定对方是否对你的证书进行了验证。
    回: ???

    - 双边证书使用相对麻烦。
    回:签名排序参数使用密钥拼接参数字符串不麻烦吗?

    - 然后还有遗留问题和习惯问题。
    回:如?
    dzdh
        81
    dzdh  
    OP
       2021-04-13 15:42:56 +08:00
    @VHacker1989 55

    所以安全就不用做了呗?无论你做任何安全都可以被逆向、动态调试?
    dzdh
        82
    dzdh  
    OP
       2021-04-13 15:43:33 +08:00
    @hxndg 有理。
    dzdh
        83
    dzdh  
    OP
       2021-04-13 15:44:50 +08:00
    @xuanbg 64

    同理,如果客户端环境安全无法保证的前提下,怎么保证『签名模式』是安全的呢?
    jhdxr
        84
    jhdxr  
       2021-04-13 16:04:12 +08:00
    Server 端到 Server 端 这一点是如何保证的?就是说,我提供了一个接口,我预期对方应该也是 server 端,但我如何可以保证这一点?
    dzdh
        85
    dzdh  
    OP
       2021-04-13 16:09:13 +08:00
    @jhdxr

    在思考这一点之前,先思考如何保证『签名模式』下对方一定也是 Server 端。

    我的接口是为了 Server 端调用而设计,客户错误使用暴露出去,屏蔽 ClientID (调用凭证)即可
    ashuai
        86
    ashuai  
       2021-04-13 16:25:18 +08:00
    https 能保证信息的完整传输吗?

    例如我给服务器发 123456,因为网络抖动,结果服务器有可能只收到 1234

    有以上可能吗?如果有,这就是签名的意义
    newmlp
        87
    newmlp  
       2021-04-13 16:27:28 +08:00
    @dzdh 你没看到我说的是增加反编译难度吗
    newmlp
        88
    newmlp  
       2021-04-13 16:32:54 +08:00
    @dzdh Xposed+JustTrustMe 就可以破解证书固定,so easy
    abersheeran
        89
    abersheeran  
       2021-04-13 16:42:34 +08:00   ❤️ 1
    把 Token 加入签名内容的签名,可以防止 Token 明文传输。把 Timestamp 加进签名内容可以防重放攻击。

    不过如果依赖于 HTTPS (这里需要注意证书),这两都可以不要。我觉得可能现在还这么做的大厂,惯性更多一点吧,毕竟代码已经写好了,可以跑了,改设计,没必要。
    3dwelcome
        90
    3dwelcome  
       2021-04-13 16:45:09 +08:00
    "所有人的质疑是否代表着 Stripe 和 Paypal 现在是极度危险状态?"

    你用国外网站举例没意义,国外信用卡支付没密码是安全的,放国内基本不可能。

    同理国外电子支付没有签名是安全的,国内设计的 API 没签名?想都别想,和钱有关的,必须加码,管他有没有用。

    这和软件加壳一个道理,你不知道破解者的能力和权限(说不定就是你隔壁同事),越套一层防范,单纯从理论上来说,就能阻断一部分破解者的尝试,也就变相代表着越安全。

    就安全系数来说,有签名的 API 和没签名的 API PK 一下,有签名的得分高。光刷公司的 KPI,也必须加。
    3dwelcome
        91
    3dwelcome  
       2021-04-13 16:47:07 +08:00
    @abersheeran “我觉得可能现在还这么做的大厂,惯性更多一点吧,毕竟代码已经写好了,可以跑了,改设计,没必要。”

    为了支付系统上出 BUG 可以甩锅,小码农根本赔不起。“看,API 设计够好了,还有签名!”
    LeeReamond
        92
    LeeReamond  
       2021-04-13 16:54:06 +08:00
    @akira 显然不对,tcp 只保证连接可靠,不保证数据可靠,单纯 http 肯定是有缺陷的,居然还有两个人点赞
    LeeReamond
        93
    LeeReamond  
       2021-04-13 16:57:56 +08:00
    @dzdh 必要性是没有,但应该也没有非必要性。很难有 api 在设计层面说脱离开 tls 我干脆就禁用,大部分是保留支持能力的,那如果已经写好了逻辑,就没有删除的理由。哈希算法成本很低,hs256 也仅在百纳秒的数量级,而不以抗哈希攻击为目的的快速哈希可以做到远更快
    timedivision
        94
    timedivision  
       2021-04-13 18:34:21 +08:00   ❤️ 1
    @dzdh 所以为了更安全,任何提高安全性的手段都是必要的呀
    dzdh
        95
    dzdh  
    OP
       2021-04-13 18:47:53 +08:00
    @ashuai 86

    "有以上可能吗?如果有,这就是签名的意义"

    没可能
    dzdh
        96
    dzdh  
    OP
       2021-04-13 18:54:39 +08:00
    @newmlp 88

    > Server 端到 Server 端。

    同理,HOOK 也可以轻松拿到用于『签名模式』的签名密钥,so easy~
    dzdh
        97
    dzdh  
    OP
       2021-04-13 19:00:08 +08:00
    @3dwelcome 90

    > 管他有没有用
    所以并不是出于安全考虑,就是为了『加』而『加』?

    > 你用国外网站举例没意义,国外信用卡支付没密码是安全的,放国内基本不可能
    公共网络的、任何人都可以进行调用的、处于公网环境的 HTTPS 接口,甚至有详细的文档。为什么他就『安全』呢?支付宝接口如果不用『签名』设计就『不安全』了?比如如果支付宝现在开始不用签名了,会导致什么问题呢?包括但不限于下单、退款、关闭订单、转账等接口,就直接像 stripe 一样 `curl -u $key https://api.alipay.com/api/transfer?to=xxx&amount=1000` 。
    dzdh
        98
    dzdh  
    OP
       2021-04-13 19:06:00 +08:00
    @3dwelcome 91

    如果有签名的时候被黑了呢,接口 bug 了呢 这不是一样吗
    dzdh
        99
    dzdh  
    OP
       2021-04-13 19:09:16 +08:00
    @timedivision

    所以是,仅仅 HTTPS 已经足够安全,所谓签名只是锦上添花?
    catchexception
        100
    catchexception  
       2021-04-13 19:23:06 +08:00   ❤️ 2
    大多数回答都不在点子上。一个是传输层,一个是业务层。
    1  2  3  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4793 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 88ms · UTC 01:14 · PVG 09:14 · LAX 17:14 · JFK 20:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.