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

少数派发了一篇文章,偶遇“大神” fastQ

  •  
  •   WngShhng · 51 天前 · 11771 次点击
    这是一个创建于 51 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我前段时间在少数派上写了一篇文章,里面提到了文件端到端加密,我自己设计了文件加密格式,就因为里面用到了 RSA 算法,然后某“大神”不干了。原文的链接: https://sspai.com/post/100448

    大神开始的评论:

    端到端加密乱入了个 RSA 非对称加密,不知道你怎么设计的总觉得很业余…
    

    说我“业余”,然后我就很不爽。于是我写了一篇文章专门分析了我的设计逻辑: https://juejin.cn/post/7524978296394350655

    跟“大神”的其他讨论在评论区可以看到。

    我 TM 就不明白了,我用 RSA 只是为了把用户的密钥记录到文件里,这本身是可选项,用来帮助用户忘记密码的时候还原密码,除外,我又没有用户的文件,根本不可能获取到用户数据。

    使用 RSA 就是为了防止被破解,因为 Android 应用别人可以使用调试、Hook 和反编译等方式获取加密用的密钥,并不安全。

    然后这“大神”依然不依不饶。说,

    其二,端到端加密从来是在可信设备上,和你 Android 反破解无关。端到端加密是保护不被中间人攻击,而不是保护数据不被客户端读取,当你说出 Android 安全显然你连端到端加密是干什么的都不知道。
    

    我赶紧我根本看不懂他的逻辑,有种驴头不对马嘴的感觉...

    最后对于我的文章和设计方案,“大神”又发表了如下高见:

    我最终还是点击了你这个掘金链接,看看你的文章,然后我发现了更多离谱的问题。
    1. 你用了用户密码直接拷贝来加长……
    你肯定不知道什么是密钥派生函数。一般来说用户输入密码,然后程序使用特定密钥派生函数派生出 master key ,然后再用 master key 来对文件加密。
    如果考虑到在用户更改密码时不重新加密解密全部文件,那 master key 还要随机生成,然后使用上述密钥派生函数派生出的 key 去加密 master key 。
    我觉得你可以去了解下 bitlocker 为什么改密码不用重新解密再加密整个盘。
    而且密码派生函数可以增加暴力破解时间,你自己实现的这个 while (passcode. Length < 48) ,难评。
    2. 按照 aes 标准,iv 应该随机生成,至于你这个 iv 生成方式不予置评;
    3. 我终于看到了你奇怪的非对称加密的用途:
    「这里的实现思路是,当写入加密文件的时候将用户设置的密钥通过 RSA 算法的公钥进行加密,并将加密的结果写入到文件。当用户忘记密钥的时候,可以读取加密文件的这部分区块,然后将这部分区块经过 Base64 编码之后上传到我们的服务器。然后,在我们的服务器上面,经过 Base64 解码成字节数组之后再使用私钥解密出用户的加密密钥。」
    这个奇怪的算法不是只要拿到这个被加密的文件,谁都能解密吗?加密的意义是不认识这个软件的人没法解密?
    但如果只要这点要求,完全可以软件内置密钥,甚至不用用户密码不是吗?
    这部分在服务器上有意义?如果是服务器还要靠用户登录来验证用户,并且每个用户有各自独立的密钥对,确实有意义。但是这又多了一个要记的登录密码——e2ee 会忘记密码,这个就不会?
    4. 拼接出 passcode 也就算了,还要从服务器把这拆回去?就不能直接返回 48 字符的 passcode 吗?反正加密解密时又会拼接回 48 字符……确实“很有意思”,我惊呆了。
    5. 除了塞进一个魔术头外,真没必要设计一个文件格式,除了自己坑自己,容易因为缺乏足够多的单元测试导致丢数据以外没啥意义。想要紧凑的二进制格式,完全可以用 msgpack bson cbor 之类的序列化格式,甚至 protobuf 之流。
    除了只能看出开发者知道的少,没看出什么……
    

    看到这评论,我都不知道说什么好了……

    1. 他最终还是没输出使用拼接 48 位有什么问题
    2. “谁”都能破解,我不知道他怎么得出的结论;
    3. 他始终没明白为什么密钥放在客户端不安全;对于用户忘记密码,这和忘记文件加密密钥是两回事。
    4. 从 48 位解析出原本简单的密码只因为那是用户自己输出的密码……
    5. 对于文件格式,谁 TM 想要紧凑二进制了,他完全没搞懂我为什么要分区块。而 protobuf 这种……它能用来设计文件格式吗?这种格式虽然紧凑,但是不好维护。

    在少数派里面,他的评论的点赞还比我多,看来很多人认可他的观点。

    我就不明白了,这是真“大神”还是假“大神”。

    因为少数派不是技术社区,开发者还要维护个人形象,本身处于弱势地位。 所以,我想在 v2 上面,都是做程序的,大家来评评理。

    第 1 条附言  ·  50 天前
    对于派生密钥的问题,这点我认。对于 RSA 的使用问题补充一些其他信息:

    只所以加 RSA 是为了把用户加密用的密钥写入到文件,这样当用户忘记密码的时候,可以帮助他解密。这是一个可选项,如果用户不信任我们,那么他可以取消勾选,那么此时仅对文件使用 AES 进行加密。

    用户的文件只存储在自己的手机上和自己的云盘上,我们不存储用户的任何信息。

    服务器记录的用户信息只和会员身份有关,和用户的笔记文件没有任何联系。

    我增加这个选项只是担心用户因为忘记密码导致数据丢失,所以提供了这个可选项,如果用户取消勾选,只需要用户自己保证记住自己的密码。
    第 2 条附言  ·  50 天前
    感谢诸位,让我学到很多,如果我再设计的一个类似的功能的话。
    那么我会采用如下方案,算是对这个帖子的总结,感兴趣的可以看一下。

    对用户输入的密码使用密钥派生生成 32 位密钥用于 AES 。
    同时使用 RSA 生成公钥和私钥,依然使用公钥将密钥写入到文件(如果用户勾选了的话)。
    然后,私钥提醒用户保存,以文本或者文件形式保存。
    当用户忘记密钥的时候,让用户提供私钥对文件解析出派生之后的密钥。
    然后让用户输入新的密钥,再使用新的密钥对文件修改密码。

    这可能是一个更妥帖的方案。
    第 3 条附言  ·  49 天前
    我已经在新的回复中向大神致歉,对于安全这块我的确欠缺一些知识。
    我的习惯是先做再学,有时候确实想当然了。
    不过我最近确实戾气很重,各位的回复也让我学到很多。
    这是一个沉痛的教训,感谢诸位。
    124 条回复    2025-07-15 17:48:58 +08:00
    1  2  
    ferock
        1
    ferock  
    PRO
       51 天前 via Android   ❤️ 1
    不评理,只看热闹


    很多点赞的人就是这思路
    webs
        2
    webs  
       51 天前   ❤️ 3
    局外人路过,觉得 “大神” 没毛病
    lloovve
        3
    lloovve  
       51 天前 via iPhone
    个人认为,你应该多看看大佬说的。端到端加密我自己理解就和 ssl 一样,协商好秘钥,中间人很难破解,我感觉你是没理解大神说的。
    WngShhng
        4
    WngShhng  
    OP
       51 天前
    @lloovve 我是文件端到端加密,其实用 AES 用户自己输入密钥就行,我用 RSA 只是为了记录用户的密钥,防止用户忘记密码而已,这有什么问题吗?
    xjoker
        5
    xjoker  
       51 天前 via iPhone   ❤️ 1
    的确密钥要使用派生算法,而不能直接截取或者扩充
    syyyyy
        6
    syyyyy  
       51 天前 via iPhone
    楼主的思路难评,老实说我觉得大神说的挺对的,记录就存在问题了,自己备份是关键
    WngShhng
        7
    WngShhng  
    OP
       51 天前
    @syyyyy 记录是可选的
    tywtyw2002
        8
    tywtyw2002  
       51 天前 via iPhone
    个人项目随便玩
    rrfeng
        9
    rrfeng  
       51 天前 via Android
    op 过于自信了,虽然这个评论的语气我也不喜欢,但是还是有点道理的。
    syyyyy
        10
    syyyyy  
       51 天前 via iPhone
    @WngShhng 就是大神说的防君子不防小人,用户自己觉得这份文件需要加密然后选了选项结果密码你那有,精准定位隐私文件?
    lloovve
        11
    lloovve  
       51 天前 via iPhone
    @WngShhng 或许等你多学学加密学的相关知识就会知道自己曾经设计的增加破解难度算法在大神眼里就是画蛇填足,我曾经也自己琢磨过加密算法,设想一种加密性又好,需要计算量又小的算法,后来我自己验证下来,自己纯属瞎折腾。
    WngShhng
        12
    WngShhng  
    OP
       51 天前
    @syyyyy 并不是,因为我不存储用户的任何文件,用户的文件存储在手机上或者自己的网盘上,而且这是可选项,用户可以选择不记录,使用 RSA 就是因为这个,最初和他讨论也就是关于 RSA 的使用的问题
    WngShhng
        13
    WngShhng  
    OP
       51 天前
    @lloovve 我没有设计算法吧,我用的是 AES 加密,只不过记录加密密钥部分使用 RSA 算法
    lloovve
        14
    lloovve  
       51 天前 via iPhone
    @WngShhng 大哥你看问题只看表面吗?难怪你理解大神说的
    lloovve
        15
    lloovve  
       51 天前 via iPhone
    不理解
    WngShhng
        16
    WngShhng  
    OP
       51 天前
    @lloovve 怎么说?
    WngShhng
        17
    WngShhng  
    OP
       51 天前
    @lloovve 还有补充一点,就是如果说我要提供用户解析密码的功能,那么我做校验也只会在客户端本身做用户身份校验,因为客户端用户可以设置独立密码
    nbndco
        18
    nbndco  
       51 天前 via iPhone
    在服务器解密用户密码的时候是怎么验证用户身份的啊
    WngShhng
        19
    WngShhng  
    OP
       51 天前
    @nbndco 客户端有独立密码或者是手机本身的物理身份识别,如果解析密码的话,会通过这种方式做身份校验
    nbndco
        20
    nbndco  
       51 天前 via iPhone
    @WngShhng 那如果我是用户 b 我把用户 a 的加密后的密码上传上来服务器能识别出这不是我的密码吗
    WngShhng
        21
    WngShhng  
    OP
       51 天前
    @nbndco 那首先得 b 用户得有 a 用户的文件,其次 a 用户勾选了把密钥记录到文件的选项(这始终只是一个可选项
    nbndco
        22
    nbndco  
       51 天前 via iPhone
    @WngShhng 你加密不就是为了防止 a 用户的文件被其他人获取后访问吗。按你这个设计我随便注册个账号就可以解密所有人的文件了?
    WngShhng
        23
    WngShhng  
    OP
       50 天前
    @nbndco 因为软件里的数据本身是私有化的,也就是存储在用户自己手机或者网盘上,所以,要想解密别人的文件,你得有他的文件,其次,如果用户觉得写入密钥的功能不妥,他可以不勾选,那么我们就不会写入,这样即便别人拿到自己的文件也无法破解,我提供这个功能只是防止用户忘记密钥,如果不勾选就需要用户自己记住密钥,仅此而已
    oott123
        24
    oott123  
       50 天前 via Android   ❤️ 2
    引入服务器在你这里确实给用户密码带来了一个薄弱环节,加密本就是为了防止文件被未授权用户查看,而你的服务器没有能力识别持有文件的人到底有没有权限获得这个文件,这就导致只要使用了这个备份密码功能,那加密就形同虚设。

    如果你的观点是,别人无法轻易获取这个文件,所以是安全的,那加密也没必要了,反正别人也拿不到……

    至于密钥派生确实应该选择成熟的派生算法,但自己做问题没有特别大,无非就是相对弱了一点。
    nbndco
        25
    nbndco  
       50 天前 via iPhone   ❤️ 12
    @WngShhng 如果你觉得用户 a 的文件永远都不会泄露,那你加密他干啥???加密的假设不就是文件会泄漏吗?
    zhy0216
        26
    zhy0216  
       50 天前 via Android
    派生算法你确实要被喷
    WngShhng
        27
    WngShhng  
    OP
       50 天前
    @oott123 密钥派生这点没问题。加密过程中是可以不勾选将用户密钥写入的,那么这样就是单纯的 AES 加密,我加这个功能只是一个可选项......防止用户忘记密钥,如果不勾选就需要用户自己记住密钥,那么即便别人拿到文件也无法破解啊
    oott123
        28
    oott123  
       50 天前 via Android
    @WngShhng 但只要这个功能被用户选择,加密就形同虚设。用户并不知道它选择了这个选项之后会将加密的安全性降低到明文级别,你给了用户虚假的安全感。这是不好的。当然我理解产品上需要一个找回密码的功能,但你需要重新思考它,起码,给每个用户分配一对独立的密钥吧?
    WngShhng
        29
    WngShhng  
    OP
       50 天前
    @oott123 我在应用的帮助文档里面有简单的说明。分配独立的密钥,技术上可以,但是会增加应用使用的复杂度,如果引入太多的东西,容易让用户费解
    nbndco
        30
    nbndco  
       50 天前 via iPhone   ❤️ 1
    @WngShhng 这个加密已经在所有层面上形同虚设了,你还在纠结用户可以不用这个功能或者用户无法理解…… 我也不知道那个 fast 说的对不对(我没看),但是你这个功能是彻头彻尾的错误
    yahon
        31
    yahon  
       50 天前
    如果只是想笔记不被除了自己的其他人查看,那么至少需要:
    1.自己只能在可信设备上查看。
    2.如传输,存储等需要保持加密状态。
    3.密文需要能解密,解密的密钥用户自己保存。

    至于用户怎么保存密钥就是另外的话题了。太复杂了容易忘,简单了容易猜。
    WngShhng
        32
    WngShhng  
    OP
       50 天前
    @nbndco 这怎么就形同虚设了呢…你不选择它不就完了吗,我提供给用户的只是一个选项
    oott123
        33
    oott123  
       50 天前 via Android
    您确实是一点儿也不愿意考虑产品决策对用户数据安全性的影响。关于安全性的讨论就言尽于此吧。

    怎么说呢,这可能会让你能做个好的产品,但不会是个安全的产品。
    nbndco
        34
    nbndco  
       50 天前 via iPhone
    @WngShhng 你有告诉用户一旦选了这个选项虽然名字里写着加密但实际上加密就失效和明文一样了吗?这就是你的产品吗,告诉用户我们加密了但实质上和明文一样,然后质问用户你为啥要选?
    WngShhng
        35
    WngShhng  
    OP
       50 天前
    @oott123 如果用户对安全性有更高的要求,那么他只需要不勾选写入逻辑就可以了。
    butterflydog
        36
    butterflydog  
       50 天前
    大神说的在理,尤其是 1-5 的意见点。别辩了,你们的沟通不在一个维度上
    WngShhng
        37
    WngShhng  
    OP
       50 天前
    @nbndco 这“和明文一样”我不知道你怎么得出的这个结论…因为我没有文件,所以我无法解析用户的文件。我觉得你的这种担心纯粹多余,因为如果我想获取用户的内容,用户输入的时候就可以获取。
    lloovve
        38
    lloovve  
       50 天前 via iPhone
    @butterflydog 感觉他有点太扛了,大神已经说的挺明白了,他楞是好像看不懂一样。
    oott123
        39
    oott123  
       50 天前 via Android   ❤️ 29
    自始至终您都只考虑了您作为服务商无法获取用户内容,而从未考虑过作为用户亦可能泄漏内容。

    作为服务商,您从未收集用户内容,因而加密与否都不会增加安全性。作为用户,若泄漏了勾选该选项的文件,加密与否都不会影响内容被泄露。

    因此,从用户的角度来说,勾选之后,加密的确和明文一样。

    而且这么多人帮您解释,您甚至不愿意点个感谢,还指望这里的用户帮您拉架,这实在是太符合我对少数派撰稿人的刻板印象了……
    nbndco
        40
    nbndco  
       50 天前 via iPhone   ❤️ 1
    @WngShhng 可能我对于安全的理解和你不同,似乎加密这个行为对你来说只是个 buzz word 。

    你的产品的安全性完全建立在攻击者无法获取到用户的数据的前提下(我不懂这个前提下加密的意义)。一旦攻击者获取到用户数据,你精心设计了一套迷惑用户已加密但是把所有解密密码拱手送给攻击者的机制,确保加密完全失效。

    确实也没啥可聊的了。
    Ljxtt
        41
    Ljxtt  
       50 天前 via Android
    @oott123 最后一句真的所见略同,刚想这么回。真的太刻板了。。
    likelylee
        42
    likelylee  
       50 天前   ❤️ 9
    怎么说呢,我先摆资历来增加说服力,国内的 FIPS140-2/3 认证,基本都是我做的。如果有做过认证的或者关心过认证的,应该就知道我是谁。
    当然你的产品不做认证前提下,随便怎么开发都没问题,但是如果你希望哪怕参考一点所谓的“最佳实践”,你就会发现那个“大神”说的大差不差。语气问题可能以下我也有,见谅。
    端到端加密没有一个准确的定义,但是按照常规的实现思路来说,“没有第三人持有任何可用于解密的材料”这个应该是共识,那么按照你现在的做法引入一个 RSA 公私钥做加密,私钥在你的服务器侧用作密码恢复,先不提所谓的算法安全强度的事情,至少你说端到端这个就不准确了。这里不讨论 RSA 用于加密的一堆要求,也不讨论怎么身份认证的事情,就单纯存在一个中心点可能会解密密码这个场景,作为明确有端到端需求的人可能就不选了。
    其他的问题,诸如 KDF 密钥派生算法,常规的方式都是考虑把密码作为 PBKDF2 的输入,提高 iteration 次数到 10000 以上,然后用派生出来的密钥作为 AES 密钥使用。AES 的 IV 要看使用场景来判断长度和生成方式,通常来说至少是随机数 96 bits 以上。在做到这些之后,你怎么做拼接 base64 之类的都无所谓。
    我们都能理解不要自创算法的重要性,但同时正确使用算法,正确的组合算法也相当重要。
    Pteromyini
        43
    Pteromyini  
       50 天前
    老实说从我勉强刚刚入门的安全理论基础的角度出发,大神说的几条一半以上是正确的,少数几条我也不懂不评价
    WngShhng
        44
    WngShhng  
    OP
       50 天前
    @likelylee 你说得对!但是我还是请教一下,如果 RSA 作为一个可选项的话,那么该如何评论呢?
    WngShhng
        45
    WngShhng  
    OP
       50 天前
    @nbndco 这说不上“把所有解密密码拱手送给攻击者”,因为私钥在我这里,攻击者没有私钥
    quicknight
        46
    quicknight  
       50 天前
    建议学一下密码学
    likelylee
        47
    likelylee  
       50 天前   ❤️ 1
    @WngShhng 想突出端到端就不要加服务器,忘了就忘了,或者参考 bitlocker 提供离线的恢复密码的助记码之类的方式。如果一定要做 RSA 且服务器保存,那么至少参考上边几楼的说法,做好身份认证之类的事情,比如额外引入 CA......
    wy315700
        48
    wy315700  
       50 天前   ❤️ 3
    作为信安科班生,我建议你认认真真学一学密码学基础,
    来一个个解释一下

    他最终还是没输出使用拼接 48 位有什么问题
    --- 为什么要用派生算法。因为用户输入的,永远会是可见字符,所以密码空间并不能占满整个密钥空间,所以要用 PBKDF 等算法,把用户输入的字符,映射到整个密钥空间去,让密钥看起来更加随机。

    “谁”都能破解,我不知道他怎么得出的结论;

    --- 你的服务器私钥是一人一钥吗,不然的话我拿别人的对应区块传上来能解密到他的密码。这个在密码学里专业术语叫做抵挡选择密文攻击。

    他始终没明白为什么密钥放在客户端不安全;对于用户忘记密码,这和忘记文件加密密钥是两回事。
    ---- 用户忘记密码允许找回 不代表可以随意让其他人拿到密码。

    从 48 位解析出原本简单的密码只因为那是用户自己输出的密码……
    ---- 良好的密码设计是不允许从 48 位解析出用户密码的,参考 PBKDF2


    另外,你的设计里还有一个很奇葩的地方,你要校验用户输入的密码是否正确,,建议用 AEAD 校验,而不是你自创的方法。
    cmdOptionKana
        49
    cmdOptionKana  
       50 天前 via Android   ❤️ 2
    支持 OP ,多数“有知识”的人只会生搬硬套,根本不管实际情况,OP 这个场景和目的与书本里的案例不一样,但他们满脑子都是书本里的案例,都不看 OP 描述的场景,不看不听,一味像复读机一样背诵自己学过的教条。
    WngShhng
        50
    WngShhng  
    OP
       50 天前
    @likelylee 其实是因为做这种笔记软件,比较担心用户数据丢失,所以才加了 RSA 这套逻辑。离线的方式还是考虑到因为 Android 本身并不安全,所有离线的逻辑都有可能被破解,身份认证除了应用级别的认证,服务器的用户信息和用户文件没有任何联系,无法用来验证。
    WngShhng
        51
    WngShhng  
    OP
       50 天前
    @wy315700 我理解你们说的,但是实际上开发的时候根本行不通,因为服务器记录的数据和用户本身没有任何联系,我服务器的用户数据只和会员信息绑定
    nbndco
        52
    nbndco  
       50 天前 via iPhone
    @WngShhng 他给你服务器发个请求你不是就解密给他了么,这不是拱手送上是啥
    WngShhng
        53
    WngShhng  
    OP
       50 天前
    @nbndco 如果不使用 RSA 加密密钥,那实现起来更容易,但是如果用户忘记了自己的加密密钥,你有什么好的方案吗?前提是,服务器的用户信息和用户的笔记文件没有任何联系。就是一个文件给你,你有什么好的方案吗?
    nbndco
        54
    nbndco  
       50 天前 via iPhone
    @WngShhng 如果没有联系就无法验证用户身份那就不能为用户解密啊,这么简单的逻辑。又要用户随意取钱又不要验证用户身份又不用带卡能做到吗?总不能什么功能都可能实现啊。
    a4526047
        55
    a4526047  
       50 天前 via iPhone   ❤️ 3
    自以为是的楼主
    WngShhng
        56
    WngShhng  
    OP
       50 天前
    @nbndco 那这样就只能让用户丢失数据了?如果用户跑来跟你要数据怎么办?
    smlcgx
        57
    smlcgx  
       50 天前 via iPhone
    「这里的实现思路是,当写入加密文件的时候将用户设置的密钥通过 RSA 算法的公钥进行加密,并将加密的结果写入到文件。当用户忘记密钥的时候,可以读取加密文件的这部分区块,然后将这部分区块经过 Base64 编码之后上传到我们的服务器。然后,在我们的服务器上面,经过 Base64 解码成字节数组之后再使用私钥解密出用户的加密密钥。」

    没咋研究密码学,只懂点非对称加密基本原理。

    你这个东西如果服务器被黑,那所有用户的文件是不是都完蛋了?私钥放在服务器上风险是非常大的,一般来说对可信设备的验证就是再加一个可信设备,防止可信设备也就是私钥被盗的情况,公钥不用加密,而且跟你用什么加密算法没关系吧
    WngShhng
        58
    WngShhng  
    OP
       50 天前
    @smlcgx 我服务器不会记录用户的文件,如果被黑,他们能拿到密钥,但是没有文件。你说的再增加一个可信设备是指什么?或者对这种情况,你有什么好的方案吗?
    sanebow
        59
    sanebow  
       50 天前 via iPhone
    别的先不说,这个“有意思”的用户密钥还原算法,如果用户设置的密码是 1234567812345678 ,还原出来不是变成了 12345678 ?换句话说,这个密钥扩充方式会导致一些更长的密码实际等价于 8 位密码,另一个例子比如 11 个 8 的密码和 8 个 8 是一样的
    WngShhng
        60
    WngShhng  
    OP
       50 天前
    @a4526047 OK ,我已经意识到我的问题,那么这种情况你有什么好的建议吗?我现在就是学习的心态
    likelylee
        61
    likelylee  
       50 天前   ❤️ 5
    @WngShhng 你看啊,如果你不考虑认证要求,不考虑最佳实践,那你的应用不论你想怎么实现都可以。现在的问题不是你想让大家认可你这个 RSA 的实现,那对不起至少我不太认可。
    如果你的出发点是 android 的安全性,可以考虑调用 TEE 去做密钥相关处理,这也是最佳实践的做法。如果你连 TEE 的安全性都存疑,可以考虑不支持 android 只做 iOS 。但是不论如何,你希望说明你的 RSA 服务器实现的安全性高于 TEE ,那至少你得从各方面都给出来做够的说服力,而不是仅仅重复“Android 本身并不安全”,因为国内几个手机的 CC MDFPP 认证也是我做的。
    自己实现一套机制没问题,我也经常会帮客户想一些奇怪的思路,比如白盒加密之类,但是不代表这些方式是足够安全的,只是在接受了某些风险的场景下可用。对于你现在的应用场景,是不是你得先想明白到底需要应对什么风险或者安全问题,然后才去看你的实现机制是不是足够的?
    WngShhng
        62
    WngShhng  
    OP
       50 天前
    @sanebow 是这样的,这当然不算最安全的做法,之前我确实没了解密钥派生
    wy315700
        63
    wy315700  
       50 天前 via iPhone
    @WngShhng
    上面有人提到了,往你服务器发个请求就行了。

    另外我为什么笃定你没有密码学基础,

    因为你不知道 IV 是明文存储的,把用户密码直接扩充成 IV ,这和把密码直接明文存下来有什么区别。


    Coursera 有个 crypto 课程 蛮好的 不知道现在还有没有。 建议看看
    Puteulanus
        64
    Puteulanus  
       50 天前   ❤️ 3
    别的不说,就说 1password 吧,创建账户的时候我记得给了一个恢复密钥的 PDF 让自己打印出来,然后提示过如果这玩意和主密码同时遗失的话,库里储存的所有数据都将无法被找回

    你觉得这样不方便,用户体验不好,所以自己整了一套设计,并且坚信(并且宣传)自己还是拥有一样的安全性,是这样吗
    WngShhng
        65
    WngShhng  
    OP
       50 天前
    @likelylee 感谢,你说的这些我确实不了解,我说的“Android 本身并不安全”,指的是 Android 应用不安全。其实我当初想的是,既然用户自己可以存储自己的文件,那么只要他能够自己保证文件的安全性就可以了,加密的逻辑主要针对的是比如网盘,让网盘无法扫描用户的文件就可以了。或者,大不了就是取消勾选那个选项。因为实际上就是一个笔记软件,如果只用 AES 加密也是足够的…RSA 这块就是担心有些用户自己忘了密码,然后跑来找我要密码…
    sofukwird
        66
    sofukwird  
       50 天前   ❤️ 2
    可以看看 bitwarden 的密码输入是如何设计的, 它客户端是开源的
    WngShhng
        67
    WngShhng  
    OP
       50 天前
    @Puteulanus 我没有宣扬…我做的是一个笔记软件,对安全性要求不如 1password 那么高吧,不过你说的这种确实是一个方案。
    WngShhng
        68
    WngShhng  
    OP
       50 天前
    @wy315700 不好意思,我确实没看懂,在我这里 IV 不是用户输入的吗?是从 48 位里截取出来的
    nbndco
        69
    nbndco  
       50 天前 via iPhone
    @WngShhng 你要是想帮用户存密码那就帮他存密码就好了
    WngShhng
        70
    WngShhng  
    OP
       50 天前
    @nbndco 存密码,像上面说的,如果服务器被破解也不好吧…或许上面提到的那个 1password 的方案,用户设置密码时候生成一个文件(可以基于 RSA ),然后让用户自己保存文件是一个比较好的方案。和你们说的差不多,公私钥每个用户唯一
    wy315700
        71
    wy315700  
       50 天前 via iPhone
    @WngShhng 你的意思是 IV 不存储,每次依赖用户输入吗,
    又是个自创协议,也行吧,和你其他问题来看这个算小问题了。
    NotLongNil
        72
    NotLongNil  
       50 天前
    大神说的是对的,楼主这个设计极大的削弱了安全性。首先使用 RSA 的方式确实有问题,再加上这种设计带来了更多的漏洞

    但是,楼主一直假设:用户愿意为了便捷牺牲安全性。在这个假设下,大神说的漏洞,从楼主的角度看,就不成问题了

    我觉得楼主既然把“安全”作为宣传,那么应该尽可能减少漏洞的发生。大部分用户并不知道他们的操作会带来哪些风险,也无法理解,你需要尽量帮他们规避这些风险,而不是假设他们愿意为了“便捷”牺牲安全性

    最后,楼主不要小看现在的黑客,你这种 RSA 的使用方式,对于有经验的人,破解并不难
    WngShhng
        73
    WngShhng  
    OP
       50 天前
    @NotLongNil 我本来是觉得,第一数据在用户那里,第二这个功能是可选的。我当初只是想防止用户数据被网盘扫描以及在网络传输过程中被网络提供商扫描。我现在确实有更好的方案了,谢谢
    Yc1992
        74
    Yc1992  
       50 天前   ❤️ 7
    不怕菜的 就怕倔的
    前者教一遍就会 后者要花费 N 倍的时间来说服 整天 “我觉得” “我认为” “我想的是”,review 这种人的代码脑袋疼
    LittleFox
        75
    LittleFox  
       50 天前
    吃瓜吃瓜,前来吃瓜
    RollingTruck
        76
    RollingTruck  
       50 天前
    也就是说, 攻击者只要去客户端拿到公钥, 然后向服务器发送请求, 就可以拿到密码. 密码安全性取决于公钥安全性, 如果公钥被窃取, 密码就会被窃取. 确实是个多余的设计, 原因: 安全性不变, 完全可以直接把密码明文直接存储在客户端, 用户忘记密码, 就从本地获取即可, 攻击者同样需要入侵客户端, 拿到密码, 只是之前是拿公钥, 现在是直接拿密码
    RollingTruck
        77
    RollingTruck  
       50 天前
    不对, 原来是用公钥加密私钥解密, 那么你怎么区分请求密码的是用户还是攻击者呢
    RollingTruck
        78
    RollingTruck  
       50 天前
    如果不作区分, 那么攻击者入侵客户端后就能拿到密码, 安全性跟客户端直接存密码也差不多
    somebody1
        79
    somebody1  
       50 天前
    25 楼充分说明了问题,整个场景是混乱的,好像解决了问题 A ,又解决了问题 B ,但是其实解决问题 A 的最佳实践跟不是这样,解决问题的 B 的最佳实践又是另一套,两不占。

    说白了就是我就想这么做,为什么这么做,说不明白,用户就该按照我这么设计的用,但是其实业界统一的认知不是。
    RollingTruck
        80
    RollingTruck  
       50 天前
    那么我认为可以加一个手机号绑定, 如果用户想要获知密码, 应该通过发短信验明身份
    RollingTruck
        81
    RollingTruck  
       50 天前
    但是这又回到经典套路了
    RollingTruck
        82
    RollingTruck  
       50 天前
    那这样设计我觉得没问题. 短信验证码力度还不够的话, 再加个邮箱验证
    cocalrush
        83
    cocalrush  
       50 天前
    感谢 学到了新知识
    xuanbg
        84
    xuanbg  
       50 天前
    我只想说密码学是一个体系而不仅仅是加密算法或者对数据加密传输。OP 你也没必要对别人的指点应激。不懂没什么的,毕竟谁也不是生而知之,学会了就行。当然,现在可能不懂也不需要学,毕竟 AI 也是挺能干的。
    xuanbg
        85
    xuanbg  
       50 天前
    另外,看了 OP 对你的产品的介绍,有几个问题还是搞不明白。
    1 、你说的文件加密,到底是在哪加密?是用户的手机上的文件进行加密还是同步到服务器的文件进行加密,还是两者都加密,或者仅对密码加密而非对文件加密?
    2 、你说的对文件加密用的是什么加密算法? AES ? RSA ?还是其他?我只看到你说 RSA 是用来加密用户的密码。
    3 、用户密码即然存在客户端,你对其加密不是多此一举吗?反正无论如何都能成功解密的,不如直接就明文保存还更简单。
    RollingTruck
        86
    RollingTruck  
       50 天前   ❤️ 2
    @xuanbg 他要做一个找回密码功能, 所以需要在服务器存储密码明文, 以便后续发送给用户. 为了在服务器存储密码, 需要把密码安全地从客户端发送到服务器, 这个过程可能泄露密码, 因此用了 RSA 加密, 私钥存在服务器用于解密, 这样一来, 除了用户, 就只有服务器能获知密码, 或者是入侵服务器的黑客. 之后, 如果收到找回密码请求, 确认是用户本人操作后, 再把密码安全地传输给客户就行. 其实我感觉用 https 就行, 自己实现容易考虑不周导致漏洞. 此外, OP 不一定是真的应激了, 也可能是激将法增加讨论热度
    RollingTruck
        87
    RollingTruck  
       50 天前
    @xuanbg 服务器存储密码明文说的不太准确, 不是直接这么存储, 准确来说是密文+私钥, 通过解密得到明文
    RollingTruck
        88
    RollingTruck  
       50 天前
    @xuanbg 我虽然没仔细看, 但估计大概就是这么个设计思路
    x7395759
        89
    x7395759  
       50 天前
    学到了,v2 还是值得,有这样深度的讨论

    @Livid 应该鼓励这样的帖子
    RollingTruck
        90
    RollingTruck  
       50 天前
    @xuanbg 常见设计应该都是服务器不存储密码, 也不提供密码找回服务. 相反, 用户忘记密码时, 也不是找回密码, 而是重置密码
    RollingTruck
        91
    RollingTruck  
       50 天前
    @xuanbg 但是这个场景不能直接套一般的重置密码. 密钥派生看起来是可能的方向
    RollingTruck
        92
    RollingTruck  
       50 天前
    我刚才想了很久, 我觉得还是不该让服务器这边帮用户保管密钥. 密钥应该由用户唯一保管. 如果服务器有密钥, 那黑客拿到密文后, 有没有可能找服务器管理员进行交易, 或者控制服务器, 获取密钥? 这是一个很严重的安全问题
    gigishy
        93
    gigishy  
       50 天前 via iPhone
    特地架个梯子来说一句,问了身边一个算是专业人士(呃,他做过不少相关的,比如加拿大 sandvine 核心),转述如下
    他简单回答 op 不是业余,是很业余,纯粹程序小子思维,完全不懂产品。最后建议 op 取消本地 rsa 记录。
    xuanbg
        94
    xuanbg  
       50 天前
    @RollingTruck 这密码找回?不是吧?正常不应该是重置密码吗,哪有存用户密码的呀。

    然后,我怎么看怎么感觉 OP 其实只是做一个记住密码呢? OP 是不是可能在想,即然记住密码了,那顺便给你加个找回功能吧。

    可是,记住密码是记在客户端的呀。假设客户端是安全可信的,或者需要的安全等级较低。那出于方便用户的考虑,可以帮用户记住账号和密码,这样用户就能实现自动登录了。
    12tall
        95
    12tall  
       50 天前
    学到了,学到了,大神还是很耐心的
    itbunan
        96
    itbunan  
       50 天前
    长知识了
    qping
        97
    qping  
       50 天前
    大神的话确实有可学习的部分,不能因为别人说自己业余就应激吧
    抱着学习的心态完全可以说自己确实“业余”,改善设计后再次求教
    大神愿意花时间和你讨论总能学到东西
    qping
        98
    qping  
       50 天前
    另外感谢分享,学到了+1
    RollingTruck
        99
    RollingTruck  
       50 天前 via Android
    @xuanbg 因为这个密码是用来给文件加解密的,丢了就不能解密了,文件内容就被完全锁死了,所以不能简单设置一个新密码
    Trojians
        100
    Trojians  
       50 天前
    吃瓜,吃瓜,看来换到 V2 上还是被喷
    1  2  
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5685 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 01:28 · PVG 09:28 · LAX 18:28 · JFK 21:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.