V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
senx0000
V2EX  ›  程序员

http 加密的正确方法

  •  
  •   senx0000 · 2022-10-25 15:35:58 +08:00 · 6254 次点击
    这是一个创建于 789 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如果不上 https 的话,直接生成一对密钥,前端应用预置对应的公钥来加密,后端直接用私钥来解密,这样一来是不是中间人就无法知道请求的具体内容了?
    除了性能问题,暂时没想到有啥其他问题,不知道大家有没有建议?
    不考虑伪造或者篡改请求的情况,需求只是实现中间人无法得知请求内容。
    第 1 条附言  ·  2022-10-26 10:47:08 +08:00
    这种方案还是无法不考虑伪造和篡改的情况,只要能拦截并修改前端内置的公钥成中间人的公钥,就等于明文传输了。
    只能稍微增加下成本,没办法防止。
    68 条回复    2022-10-27 02:25:36 +08:00
    gam2046
        1
    gam2046  
       2022-10-25 15:43:26 +08:00
    http 加密的正确方法 就在你的如果里了,TLS 就是正确方式。

    不管你采用对称算法还是非对称算法,由于客户端环境不可信,所以密钥都是明文的。

    再如果客户端、服务端运行环境都是可信的。

    由于密钥是固定的,仍然存在统计学意义上的破解可能。

    无论如何,放弃 TLS ,自己造轮子,都是工作量更多,且效果更差。
    moshiyeap100
        2
    moshiyeap100  
       2022-10-25 15:44:19 +08:00
    https 不就是这样干的?
    Noicdi
        3
    Noicdi  
       2022-10-25 15:46:04 +08:00 via iPhone
    https 不也是用密钥吗
    mxT52CRuqR6o5
        4
    mxT52CRuqR6o5  
       2022-10-25 15:46:33 +08:00
    我的建议是你怎么开心怎么来
    senx0000
        5
    senx0000  
    OP
       2022-10-25 15:48:37 +08:00
    已经上 https ,主要是客户还不满意,非要国密,https 现在还没有普遍支持,不得已求其次,无奈。
    RRyo
        6
    RRyo  
       2022-10-25 15:49:05 +08:00
    1+1 的正确答案 首先排除 2 是吧
    如果是出于学习密码学目的, 你照着 TLS 早期版本自己造一遍轮子倒是无所谓, 实际使用上来先排除正确答案是啥意思...
    RRyo
        7
    RRyo  
       2022-10-25 15:50:06 +08:00
    @senx0000 #5 国密有 SM2 的证书
    xiqishow
        8
    xiqishow  
       2022-10-25 15:50:09 +08:00   ❤️ 1
    https 更多是一种端到端的认证,比如在 app 中使用 ssl pinning ,锁定认可的证书。
    加密应用协议很多银行类的 app 都在使用,但选择如何加密,比如密钥等加密参数如何下放,如何保护客户端的加密方法,比如代码混淆,应用加固,防止反编译,被动态调试都是需要解决的问题。
    而在 web 端,保护加密资产感觉更困难一些,毕竟就是 js 被混淆了一下,只是读起来恶心但不是完全不能解(成本问题),可能会通过 wasm 等把加密资产二进制化更好一些
    senx0000
        9
    senx0000  
    OP
       2022-10-25 15:53:12 +08:00
    至少看看能不能找到个不安全的理由给客户,让他放弃。
    Fule
        10
    Fule  
       2022-10-25 15:53:14 +08:00
    实现安全性 Rule No.1:不要自己造轮子。
    julyclyde
        11
    julyclyde  
       2022-10-25 15:53:17 +08:00   ❤️ 3
    @senx0000 用国密证书就行了
    对付 sb 要用 sb 自己的方法
    tool2d
        12
    tool2d  
       2022-10-25 15:53:25 +08:00
    早期网游不都没上 HTTPS ,走的都是自由加密协议,又不是不能用。

    后来苹果强制开 HTTPS ,你不开加密,APP 都没办法上线,很大程度推动了加密协议的标准化流程。
    senx0000
        13
    senx0000  
    OP
       2022-10-25 15:54:05 +08:00
    不解决其他问题,只解决中间人能看明文的问题
    moshiyeap100
        14
    moshiyeap100  
       2022-10-25 15:58:27 +08:00
    @senx0000 那就用国密算法自己对请求内容再进行一边加密,同时保留 https 。
    senx0000
        15
    senx0000  
    OP
       2022-10-25 16:01:29 +08:00
    @RRyo @julyclyde 国密证书只有国产的一些浏览器支持吧
    Leonard
        16
    Leonard  
       2022-10-25 16:02:05 +08:00
    @tool2d #12 苹果强制的 HTTPS 好多年前就在说,到现在还没落实
    heiher
        17
    heiher  
       2022-10-25 16:02:40 +08:00 via Android
    能说服客户认可的加密就是好加密 :P
    XiLingHost
        18
    XiLingHost  
       2022-10-25 16:04:58 +08:00
    @senx0000 只解决中间人看明文的问题,建议 base64“加密”
    leaves615
        19
    leaves615  
       2022-10-25 16:06:23 +08:00
    http 要求加密,无非是解决中间人攻击的问题,用非对称加密就好了。https 也是用来解决中间人攻击的问题。

    客户端的明文或者密钥泄漏,是客户端的本地安全问题,应在客户端层解决。而不是通过链接层的安全策略来解决客户端安全。
    huangsijun17
        20
    huangsijun17  
       2022-10-25 16:17:10 +08:00
    国密也还是 HTTPS ,还是 SSL 证书,只是使用了 SM2 、SM3 协议。
    t6attack
        21
    t6attack  
       2022-10-25 16:24:55 +08:00   ❤️ 2
    在 http 时代,qq 邮箱就是这么干的,密码是 rsa 加密一下传到服务端。
    它的公钥我还有记录:
    CF87D7B4C864F4842F1D337491A48FFF54B73A17300E8E42FA365420393AC0346AE55D8AFAD975DFA175FAF0106CBA81AF1DDE4ACEC284DAC6ED9A0D8FEB1CC070733C58213EFFED46529C54CEA06D774E3CC7E073346AEBD6C66FC973F299EB74738E400B22B1E7CDC54E71AED059D228DFEB5B29C530FF341502AE56DDCFE9
    zhangxh1023
        22
    zhangxh1023  
       2022-10-25 16:31:20 +08:00
    客户要的国密应该是要在 https 上再套一层加密吧。
    你就用客户端随机生成一个 aes 的密钥,然后加密请求数据,再用 sm2 加密一下密钥传给后端。
    selfAccomplish
        23
    selfAccomplish  
       2022-10-25 16:38:34 +08:00
    HTTPS 算法使用 RSA2048 位以上。然后前端使用 SM2 算法 公钥加密,后端解密。
    性能影响可以忽略吧,除非服务器是小霸王学习机哈哈
    tysb777
        24
    tysb777  
       2022-10-25 17:13:17 +08:00
    国内有一家厂商做到了服务器上安装 SM2 和 ECC/RSA 两个证书,可以自由切换。在国产浏览器里加载 SM2 ,在其他里加载 ECC/RSA 。

    不过 SM2 证书现在价格很高,可以捞点油水。
    ren2881971
        25
    ren2881971  
       2022-10-25 17:30:16 +08:00
    @senx0000 他有国 M 浏览器么 就要上国密 SSL 。
    dzdh
        26
    dzdh  
       2022-10-25 17:52:30 +08:00
    可以 GM+RSA 一起上
    JohnBull
        27
    JohnBull  
       2022-10-25 18:05:41 +08:00   ❤️ 1
    在加密算法领域,不是数学家的话就不要搞发明创造.
    老老实实上 https 最安全
    brader
        28
    brader  
       2022-10-25 18:06:55 +08:00
    我建议你 https 照常上,这是给你自己的保障,然后说下我的使用国密解决中间人窃取的想法:客户端生成一个临时的密钥,使用 RSA 公钥加密,请求消息使用国密算法和刚才的临时密钥进行加密,请求消息带上密钥一起发送给服务端,服务端接收到的请求,使用 RSA 私钥解密出密钥,使用密钥进行国密解密。
    iOCZ
        29
    iOCZ  
       2022-10-25 18:08:20 +08:00
    https 也能用国密吧
    sxyclint
        30
    sxyclint  
       2022-10-25 18:12:18 +08:00
    直接用国密版本的 HTTPS ,然后会发现有些浏览器不支持,这样就说服他了
    flyqie
        31
    flyqie  
       2022-10-25 18:13:28 +08:00 via Android   ❤️ 1
    如果是纯 web 项目的话,那这样就有个问题。

    你既然是用了公私钥加密,那我可不可以用中间人方案有针对性的来拦截并修改你公私钥加密的代码?
    flyqie
        32
    flyqie  
       2022-10-25 18:15:45 +08:00 via Android
    @flyqie #31

    这个问题 tls 是通过在客户端预置可信证书来规避的,很好奇你打算怎么做。
    olaloong
        33
    olaloong  
       2022-10-25 18:17:56 +08:00 via Android
    是可以啊,有不少 toB 厂商的接口请求响应体都是全加密的,SM4 加密 SM2 签名再套个 https 传输
    我们 H5 端就是前端 SM4 加密请求到后端的
    ochatokori
        34
    ochatokori  
       2022-10-25 18:20:06 +08:00 via Android
    不用 https 的话,那我中间人直接在客户端接收你那个写死的公钥的时候把你公钥给替换了,不还是能随便解密你的密文,你客户端又发现不了公钥是假的(中间人用你原来的公钥和服务器通信,服务器也发现不了客户端在使用假公钥)
    wangritian
        35
    wangritian  
       2022-10-25 18:28:17 +08:00
    防中间人最关键的一步在于客户端要用 ca 证书验证服务器证书,且不信任系统提供的 ca 证书
    加密算法只要不用太落后的就都安全
    浏览器环境,就买大机构的证书; app 环境,可以自签名,然后把 ca.crt 丢进客户端自己校验
    mritd
        36
    mritd  
       2022-10-25 18:46:11 +08:00 via iPhone
    国米的东西… 糊弄糊弄就行了,毕竟他们又不懂你说是不是?
    wanguorui123
        37
    wanguorui123  
       2022-10-25 18:49:16 +08:00 via iPhone
    中间人反向代理你的请求,糊弄一下别人可以
    izzy27
        38
    izzy27  
       2022-10-25 19:08:16 +08:00   ❤️ 1
    用自己设计的加密算法是很危险的
    joshu
        39
    joshu  
       2022-10-25 19:45:24 +08:00
    你这个方法应该不防重放
    momocraft
        40
    momocraft  
       2022-10-25 19:46:37 +08:00   ❤️ 1
    需要国密的客户看得出你用什么加密吗?
    swulling
        41
    swulling  
       2022-10-25 19:49:22 +08:00 via iPhone
    客户让怎么搞就怎么搞,糊弄过去就完了。哪那么较真
    heiher
        42
    heiher  
       2022-10-25 20:10:23 +08:00 via Android
    我理解的中间人问题防止的是密钥(公钥)分发过程中被篡改,使中间人有能力解密密文。TLS 是服务端动态分发公钥,而不是客户端静态预置,所以还需要 CA 机制验证公钥是不是可信的,确实来自真实服务端。如果是客户端静态预置公钥,那么仅在传输层面是没有中间人攻击的可能性的。客户端静态预置公钥的问题之一是一旦服务端的密钥泄漏,没有吊销机制。
    cwek
        43
    cwek  
       2022-10-25 20:22:01 +08:00
    TLS 有 SM 魔改方案。
    nlzy
        44
    nlzy  
       2022-10-25 20:26:23 +08:00
    遇到客户要求使用国密的话,建议不要自己发明密码协议,也不要整什么 RFC 8998 ,就正常用 TLS ,然后在应用层用国密加密一下完事。
    lovelylain
        45
    lovelylain  
       2022-10-25 20:28:08 +08:00 via Android
    直接非对称加密有个问题是能加密的明文长度太小,分组多次非对称加密的话性能又太差,可以改成前端随机生成对称密钥,用公钥加密对称密钥,对称加密真实明文。本身 https 在加密方面也基本是这个原理,只是引入了证书体系来将公钥可靠的传给前端,你写死在代码里跳过证书体系也不是不行。当然正如楼上所说,非必要情况下最好还是用现成的 https ,以免有未考虑到的问题,https 应该也是支持国密的。
    systemcall
        46
    systemcall  
       2022-10-25 22:33:18 +08:00
    国密的东西,政治上站好队就行了
    多一事不如少一事,不要自己造轮子,能跑起来就行了
    xyjincan
        47
    xyjincan  
       2022-10-25 22:43:04 +08:00 via Android
    拉 VPN ,国产的
    cnrting
        48
    cnrting  
       2022-10-25 22:51:00 +08:00 via iPhone
    客户什么都不懂的,能忽悠就忽悠🐶
    ajaxgoldfish
        49
    ajaxgoldfish  
       2022-10-25 23:03:20 +08:00 via Android   ❤️ 1
    我就是干这个的,看我之前发的贴。国密有非对称 sm2 现在上海国密局要求过检硬件加密设备以及软件程序都要支持国密,杂凑有 sm3 类似于 sha256 ,用 sm2 就得用 sm3 ,用 sm2 需要有特殊支持 sm2 的客户端来支持,否则大部分内置都是 RSA 的。而且我说个大问题,现在 sm2 的性能大约是 RSA 的 0.5 倍,这里说的是吞吐量以及 TPS 。sm147 为对称,就不展开说了。
    Laussan
        50
    Laussan  
       2022-10-25 23:38:00 +08:00
    如果你跟客户可以线下交付公钥应该就没啥问题?
    julyclyde
        51
    julyclyde  
       2022-10-26 09:03:55 +08:00
    @senx0000 确实是只有少部分国产浏览器支持
    但客户肯定可以接受
    这东西都是全套的
    newmlp
        52
    newmlp  
       2022-10-26 09:47:41 +08:00
    放弃 tls ,然后自己再实现一遍 tls ?意义在哪?
    libook
        53
    libook  
       2022-10-26 10:11:12 +08:00   ❤️ 2
    HTTPS 的安全性其中有一点是客户的系统或浏览器预装信任的 CA 证书,不管中间人怎么折腾,只要本地的证书都是可信的就不会有问题。
    而题主的方案的缺陷在于前端的公钥是需要跟随前端页面资源从服务器拉下来的,这个过程中中间人可以拦截 response 然后替换成自己的公钥。又因为真正的公钥是任何人只要访问服务器就可以拿到的,所以可以形成完整的中间人攻击链路。
    除非这个前端不只是网页,比如是 App 内嵌的 WebView ,由 App 预置公钥。
    unco020511
        54
    unco020511  
       2022-10-26 10:21:30 +08:00
    tls 就是安全的呀,为啥还要自己造轮子呢
    barbery
        55
    barbery  
       2022-10-26 10:36:55 +08:00
    最近过等保,https 加密那边不认,厂商就是要求再进行加密传输
    senx0000
        56
    senx0000  
    OP
       2022-10-26 10:41:18 +08:00
    @libook 对,核心缺陷就是这个,公钥是可以被替换的,这种方案只是增加了一些成本,防止不了被替换,一旦替换等于就是明文传输了。
    libook
        57
    libook  
       2022-10-26 11:04:54 +08:00   ❤️ 1
    @senx0000 #56 其实你在主题里描述的方案,把一些安全漏洞都补好,基本就是 TLS 了,所以不如直接上 HTTPS ,毕竟经过那么多人检验可行。

    @barbery #55 敏感信息是需要二次加密的,不是说 HTTPS 不行,而是需要在 HTTPS 基础上再进行一次加密,因为 HTTPS 是用户确保安全的,但用户可以主动或被动放弃这个安全(比如装私签证书);二次加密是服务方确保安全的,即用户难以去掉这个安全机制。具体哪些属于敏感信息可以参考 GB/T-35273 附录 A 、B 。
    gaifanking
        58
    gaifanking  
       2022-10-26 11:12:20 +08:00
    感觉都没回复在点上,你这种公私钥加密我理解为 RSA 吧,主要问题是公钥加密对长度有限制。
    512bit 的公钥,最长只能加密长度为 53 的明文,所以不适合用来加密内容,只适合加密一个对称加密算法的密钥。
    xz410236056
        59
    xz410236056  
       2022-10-26 11:26:46 +08:00
    @tool2d #12 并不是,实际上国内推动 https 是国内大厂,14 年大家一起推的,主要是防止国内越来越严重的运营商劫持和 DNS 污染
    tuwulin365
        60
    tuwulin365  
       2022-10-26 12:12:19 +08:00
    TLS 传递 SM4 或者 SM2 密钥,后续用 SM4 或者 SM2 加密
    Daiwf
        61
    Daiwf  
       2022-10-26 12:13:19 +08:00
    国密证书用不起来的 ,客户都得用国产浏览器才行。只能单位内部用用。
    tuwulin365
        62
    tuwulin365  
       2022-10-26 12:13:21 +08:00
    @gaifanking 长度不是问题,分段加密就是了。主要是非对称加密速度太慢。
    Huelse
        63
    Huelse  
       2022-10-26 12:22:08 +08:00
    直接定制客户端吧,大赚一笔
    tool2d
        64
    tool2d  
       2022-10-26 12:51:17 +08:00
    @senx0000 "核心缺陷就是这个,公钥是可以被替换的"

    验证一下公钥的签发机构就可以了,你稍微逻辑缜密一点,根本不可能被替换。
    IvanLi127
        65
    IvanLi127  
       2022-10-26 13:03:52 +08:00 via Android
    我的观点是,正确方法就是要么改用国密算法的 HTTPS ,要么放弃 HTTPS ,在应用层里套国密。 套娃可能影响加密效果。
    gaifanking
        66
    gaifanking  
       2022-10-26 14:50:19 +08:00
    @tuwulin365 对头,而且 RSA 加密要加 padding 等导致数据变大,核心就是 RSA 不适合,而不是 RSA 直接加密不安全。
    kokutou
        67
    kokutou  
       2022-10-26 14:58:46 +08:00 via Android
    https://zhuanlan.zhihu.com/p/144272882

    看看各种国内的云服务商的文章呗。。。他们肯定遇到过这种需求。
    还有创宇盾。。

    国产的东西要找国产的服务商。。。
    ssse1
        68
    ssse1  
       2022-10-27 02:25:36 +08:00
    真的很需要加密的情形自己造轮子出 bug 了谁负责。这些东西不好写的,发展了那么多年了才成这样。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   880 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 20:02 · PVG 04:02 · LAX 12:02 · JFK 15:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.