V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
ysmood
V2EX  ›  分享创造

利用 github id 加密隐私数据(测试送 100 元红包)

  •  2
     
  •   ysmood ·
    ysmood · 2024-01-02 02:59:02 +08:00 · 3708 次点击
    这是一个创建于 374 天前的主题,其中的信息可能已经有所发展或是发生改变。

    git 仓库: link

    如果你感兴趣的话,也可以在本帖子里留加密信息给我玩:

    echo '你的微信 id' | whisper -b -e @ysmood
    

    如果超过 10 个人留了微信账户,就随机给一个人送 100 元红包。

    用法 01

    比如 hr 想在某个帖子分享自己的邮箱给贴主,贴主的 github id 是 jack:

    echo '[email protected]' | whisper -b -e @jack
    

    解密:

    echo 'AQABATIhJwkBASD4gfrf' | whisper -b
    

    这样就只有贴主能看到邮箱了,不会泄露自己的隐私了。

    用法 02

    比如想在 github issue 上分享自一些敏感的调试数据给 repo 的开发者用于复现某种 bug ,假设 repo 的开发者 github id 是 jack:

    whisper -e @jack 截图.jpg > 加密.jpg
    

    这样的话就只有 jack 本人可以看到这个截图了。

    用法 03

    再比如用来在 Github 仓库中与团队成员共享数据库密码,只要成员能克隆仓库,就无需生成新的密钥对或进行额外的任何配置,零门槛。

    比如, 想共享 .env 文件给 Jack 和 Time ,他们的 github id 是 jacktim:

    whisper -e=@jack -e=@tim .env > .env.encrypted
    

    commit .env.encrypted 到 git 仓库.

    Jack 就可以 clone 仓库然后解密:

    whisper .env.encrypted > .env
    

    关于 Whisper 和 Age 的对比: link

    34 条回复    2024-01-04 12:12:37 +08:00
    geelaw
        1
    geelaw  
       2024-01-02 03:43:46 +08:00   ❤️ 2
    随便看了几眼,看起来有如下问题:

    - 弄混了 AES 块长度和密钥长度,并且不知为何要先对随机数取 MD5 再当作 AES 密钥
    - 加密算法看起来没有保证选择密文攻击下的安全性
    - 引用 RFC 4880 Sect. 5.13 以论证合理性的部分似乎没有起到密码学安全性(所引用段落的目的)的作用
    superkkk
        2
    superkkk  
       2024-01-02 08:29:33 +08:00 via iPhone
    为何不直接在帖子里留下自己的 rsa 公钥。这样其他人加密后的信息只有有私钥的人才知道。
    kindjeff
        3
    kindjeff  
       2024-01-02 08:48:53 +08:00 via Android
    是用用户 github 的公开公钥加密数据吗,还挺有意思的
    Masoud2023
        4
    Masoud2023  
       2024-01-02 10:13:33 +08:00
    真有这种需求建议老老实实 GPG
    ysmood
        5
    ysmood  
    OP
       2024-01-02 11:15:55 +08:00
    @geelaw 多谢指教!

    > - 弄混了 AES 块长度和密钥长度,并且不知为何要先对随机数取 MD5 再当作 AES 密钥

    你可以读读 golang 的文档 https://pkg.go.dev/crypto/aes#NewCipher 这里并没有弄混,是为了选择块长度才做 md5 的,保证不论使用什么长度的 secret ,块长度都是 128bit 。请问这有啥安全问题吗?

    > 加密算法看起来没有保证选择密文攻击下的安全性

    这个只有非常限定的情况下才能发生,而且只发生在 rsa 上,加个 khdf 就好了。现在都只推荐使用 ecdsa 或者 ed215519 了,rsa 不推荐使用。我有时间修复下。

    > 引用 RFC 4880 Sect. 5.13 以论证合理性的部分似乎没有起到密码学安全性(所引用段落的目的)的作用

    这个不是为了安全设计的,是为了快速验证密码是否正确。因为 AES 任意密码都可以 decode 内容,即便是密码错误也可以 decode ,不过会 decode 成无意义的数据。
    galenzhao
        6
    galenzhao  
       2024-01-02 11:23:55 +08:00
    不错 ,相当于用 github 来获取分发的公钥,
    不过像我这个有一堆公钥在的 ,不太好整
    ysmood
        7
    ysmood  
    OP
       2024-01-02 11:26:56 +08:00
    @superkkk 当然可以,whisper 其实就是在为你做这个事情,只是更便利了而已。
    ysmood
        8
    ysmood  
    OP
       2024-01-02 11:27:16 +08:00
    @Masoud2023 你看看 age 库,用的人还是非常多的,证明还是有很多人不太想在某些场景下使用 gpg 的。
    ysmood
        9
    ysmood  
    OP
       2024-01-02 11:35:45 +08:00
    @galenzhao

    > 不过像我这个有一堆公钥在的 ,不太好整

    whisper 已经解决这个问题了,它可以自动选择密匙,也支持公钥过滤。原理在于它 embed 了 公钥的 hash 到加密后的内容,你可以试试。

    比如这是用你的第三个公钥加密的信息,你直接可以用 whisper 解密,不需要任何配置:

    echo 'hi' | whisper -b -e @galenzhao:IfQaAz

    AQABAba9zT8BAYAD0JJoTb40bb5vxJshk9cU9p8EzsqDpnGMcEnbAE2ppJjoXsZcLyyiEuhb96G4yDCiU5CCOWPUANLxWK2ZMzWxc+y5Sa0XIy44Z/kEdu+OhZ+sYDuzhHAF1Bptjof5eFRDAx08Tl63en15/SDHB3WeGiQZhCTlgz44wUPZ6qcD5mvJhkgjpDlvAwZuUTuRxlDrEvAGjo03DTlu1xqUk8HhU2TtrzI4Zt86ymNc/JNtd8MQ8qi6FVanGIQATUZ7URJH3i22NmCN6NKek28iXCrOgtva53scJHuDbkfYrkEJBJl7WOdiHeX8jbvR/0Y3oJML6/kFgdYwi6t93zYwwIsKaT9hYHsxh0EvPODn9E9lHyYN142TwhnUllz8vd+dIR53YEXJfYjhoStpbVrpQ5SQHswRlc5F/kV5FiKWMKKTggRRk5FNEPIycuyAQiGyqPT4HVZrCFOOgxPcDxYWbsskHaZAy4zUxHRfpvAVRfgza+m5sQHQUpn6TiE5Q+ucf6d5+AEWbCxMuWSyJ8qwMSQlbs9K/v14
    ysmood
        10
    ysmood  
    OP
       2024-01-02 11:48:02 +08:00
    @geelaw 我看了下 golang 的 rsa.EncryptOAEP 感觉也足够安全了,不太需要再做额外的优化了。
    ysmood
        11
    ysmood  
    OP
       2024-01-02 12:10:54 +08:00
    @geelaw 要说 whisper 代码里最有争议的地方,应该是 ed25519 转 ecdsa 的安全性问题。目前没有太好的办法,推荐加密还是用 ecdsa 比较好,ed25519 只用于签名。

    https://github.com/ysmood/whisper/blob/0e43607cd36c869bdaa9a03f63701eb5603ffec3/lib/secure/key.go#L267

    要是能帮忙把这个问题解决了那就厉害了。
    galenzhao
        12
    galenzhao  
       2024-01-02 12:18:17 +08:00
    @ysmood 我的意思是,一堆公钥,但是对应的每个私钥都在不同的机器,
    如果想要都能 decode ,那就得把用户所有公钥都搞一份数据,数据量大的话就不好整了,
    ysmood
        13
    ysmood  
    OP
       2024-01-02 12:25:17 +08:00 via Android
    @galenzhao 很容易呀,那你就把第 1 个公式当成通用的公式呗,只需要把它的密钥拷贝到所有的机器上就够了。

    就相当于你每台机子都要登微信才能用微信一样的道理,你至少要有一个密钥是所有的电脑上才都有的你才能方便别人给你发私信,不管你用什么工具都是一样的。
    ysmood
        14
    ysmood  
    OP
       2024-01-02 12:26:56 +08:00 via Android
    抱歉订正下:公钥,不是公式
    equationzhao
        15
    equationzhao  
       2024-01-02 13:01:53 +08:00
    Enter passphrase for private key: Error: inappropriate ioctl for device

    是不支持输入 passphrase 吗
    equationzhao
        16
    equationzhao  
       2024-01-02 13:04:31 +08:00
    @equationzhao terminal 是 warp 和 mac 自带的 terminal
    ysmood
        17
    ysmood  
    OP
       2024-01-02 14:12:07 +08:00
    @equationzhao 我试了下 warp 我也是 mac ,没有任何问题,可以正常输入 passphrase ,你用的是 zsh 吗?

    可以通过

    echo $0

    来看用的什么 shell 。
    lambdaq
        18
    lambdaq  
       2024-01-02 15:24:09 +08:00
    @kindjeff 估计是。。LZ 的公钥是 https://api.github.com/users/ysmood/keys
    InDom
        19
    InDom  
       2024-01-02 15:31:11 +08:00
    得到一个有用的东西,https://github.com/{YOUR_ID}.keys

    感谢楼主。
    Senorsen
        20
    Senorsen  
       2024-01-02 15:42:30 +08:00
    挺有意思的思路,不过 ls 提到的选择哪个 ssh 密钥确实也是个问题

    AgABATIhJwkBASBFQL8tdSW0/+uQO2IAuO2i8QC3rFPO8mNyH5gKAPnyaJBbNXbrLZz/GWQ1MskYC+2ovspYdK6+kWIl5w==

    这密文还挺长的,然后请教下为啥需要一个 background agent ?
    ysmood
        21
    ysmood  
    OP
       2024-01-02 16:55:25 +08:00   ❤️ 2
    @lambdaq 不用这么麻烦,这样就够了 https://github.com/ysmood.keys
    ysmood
        22
    ysmood  
    OP
       2024-01-02 17:10:45 +08:00
    @Senorsen 感谢试用!

    > ssh 密钥确实也是个问题

    关于选哪个 ssh 密匙一般不存在问题,大部分人机子里都有。而且可以加冒号选择某个 ssh pub key ,比如 "@ysmood:abc"

    > 这密文还挺长的

    密文已经很短了,你看 gpg 生成的比这可能长几倍。同类工具这个应该是最短的。

    > 请教下为啥需要一个 background agent ?

    因为 private key 通常是一个文件,任何系统里的 app 都可以读取到这个文件,这很不安全。所以一般都会用一个 passphrase 加密这个 private key ,只有用的时候才解密到内存里使用,这样任何系统里的 app 都没法获取真正的 private key 。但这会引入一个新问题,每次都输入 passphrase 非常麻烦,所以一般加密工具都会提供一个 agent 来缓存 passphrase 到内存,比如 ssh-agent ,这样只有重启电脑的时候才需要再输入一次。

    这是一个非常通用的技巧,Apple 的 Touch ID 也是这样的,只不过它用了一个专用 chip 来缓存,掉电了就得重新输入 passcode 。
    lambdaq
        23
    lambdaq  
       2024-01-02 17:17:50 +08:00
    geelaw
        24
    geelaw  
       2024-01-02 19:18:20 +08:00 via iPhone
    @ysmood #5

    你的第一段回复表明确实弄混了块长度和密钥长度,AES 的块长度永远是 128 位,密钥有三种长度。不存在“选择”块长度这种操作,因为没的可选。

    第二段回复表明没理解什么是选择密文安全性。把公钥加密和 AES 以 OFB 模式(不是选择密文安全)结合时当然不可能期待选择密文安全性。
    ysmood
        25
    ysmood  
    OP
       2024-01-02 20:04:59 +08:00
    @geelaw #24

    > 你的第一段回复表明确实弄混了块长度和密钥长度,AES 的块长度永远是 128 位,密钥有三种长度。不存在“选择”块长度这种操作,因为没的可选。

    我意思是保证不论使用什么长度的 secret ,最终都是使用 AES-128 ,这是 golang 的标准库规定的用法。抱歉没有很专业的表达我的意思,我这里并不在乎块的长度。所以我这个操作又安全风险吗?


    > 第二段回复表明没理解什么是选择密文安全性。把公钥加密和 AES 以 OFB 模式(不是选择密文安全)结合时当然不可能期待选择密文安全性。

    抱歉我理解错了你的意思,你意思就是信息可以被篡改吧?这个攻击又不可以破解具体内容。whisper 不是提供了 sign 吗,文档里最后有提到 sign 的用法,如果你觉得你的数据有被中间人篡改的风险,用 whisper 的 -s 参数就行了。
    geelaw
        26
    geelaw  
       2024-01-03 04:27:10 +08:00 via iPhone
    @ysmood #25

    第一个问题,我不知道有没有风险,但是这会导致没有选择超过 128 位密钥的意义,限制了最大安全性。

    第二个问题,对密文签名只能保证密文“被谁同意”,不能保证明文来自于谁,也不能保证密文在加密结束之后没有被“有意义地修改过”,后者是选择密文安全性的要求。

    “明文来自于谁”的攻击:A 向 B 发送消息 X ,经过加密得到 C ,再对 C 签名得到 D ,并通过网络发送 D ,使坏者 M 截获 D 并拿出 C ,然后重新以 M 的身份签名 C 得到 E ,发送 E 给 B 。

    假设 B 公开接受任何人 Y 的消息 Z ,如果 Z 包含了某个密码,则允许 Y 获得权限。上述场景中 A 知道密码但 M 不知道,但 M 可以获得权限。

    “修改密文”的攻击:类似上面的,但重新签名之前修改 C 获得 C' 并对 C' 签名。

    除非收信人只收取某个特定的人(以签名所用的公钥识别)的信息(因此 M 重新签名不会被接受),否则上述场景可以成立。但如果收信人只收取特定的人的信息,则没必要每次通信都用公钥加密。
    Senorsen
        27
    Senorsen  
       2024-01-03 10:53:20 +08:00
    @ysmood #22
    >> 请教下为啥需要一个 background agent ?

    > 因为 private key 通常是一个文件,任何系统里的 app 都可以读取到这个文件,这很不安全。所以一般都会用一个 passphrase 加密这个 private key ,只有用的时候才解密到内存里使用,这样任何系统里的 app 都没法获取真正的 private key 。但这会引入一个新问题,每次都输入 passphrase 非常麻烦,所以一般加密工具都会提供一个 agent 来缓存 passphrase 到内存,比如 ssh-agent ,这样只有重启电脑的时候才需要再输入一次。
    >
    > 这是一个非常通用的技巧,Apple 的 Touch ID 也是这样的,只不过它用了一个专用 chip 来缓存,掉电了就得重新输入 passcode 。

    谢谢回答,不过我的问题在于,只使用“加密”是不需要私钥的,只需要拉取 GitHub 上目标用户的公钥,因此无条件启动 agent 的行为比较怪。
    ysmood
        28
    ysmood  
    OP
       2024-01-03 12:09:45 +08:00
    @geelaw #25

    > 但是这会导致没有选择超过 128 位密钥的意义,限制了最大安全性。

    openssl 默认用的 128bit ,在 whisper 的使用场景已经够安全了,因为这个 aes key 只会被使用一次就扔了。我加了个选项: https://github.com/ysmood/whisper/blob/86d93ffbb3897d1739664da5597f6b85d1045be4/lib/piper/encodings.go#L74-L75

    > 第二个问题,对密文签名只能保证密文“被谁同意”,不能保证明文来自于谁,也不能保证密文在加密结束之后没有被“有意义地修改过”,后者是选择密文安全性的要求。

    whisper 没有这个问题,readme 里已经说明了 sign 验证需要显示声明发件人的 github id 用以验证,否则你就不在乎被篡改。你不可能再签名的,验证会失败。

    > 除非收信人只收取某个特定的人(以签名所用的公钥识别)的信息(因此 M 重新签名不会被接受),否则上述场景可以成立。

    和上一个问题一样。

    > 但如果收信人只收取特定的人的信息,则没必要每次通信都用公钥加密。

    这也不是安全问题,只是某种大部分人不在乎的性能优化,whisper 的使用场景是单次的无状态通信。
    ysmood
        29
    ysmood  
    OP
       2024-01-03 12:16:09 +08:00
    @Senorsen #22

    > 谢谢回答,不过我的问题在于,只使用“加密”是不需要私钥的,只需要拉取 GitHub 上目标用户的公钥,因此无条件启动 agent 的行为比较怪。

    多谢,这是个很好的建议,我把它改成只有需要的时候才启动好了。
    加 sign 或者解密的时候都需要 passphrase ,非常常用。我建议是即使是发送的时候也加个 sign ,更安全。
    geelaw
        30
    geelaw  
       2024-01-03 12:50:50 +08:00 via iPhone
    @ysmood #28

    第二个问题,似乎你没有理解第一个攻击例子的场景:A 要和 B 说话,B 选择去听任何人的话,M 达成的效果是 M 不知道 A 想说什么,但是让 B 以为 M 说了 A 本来要说的话。B 是用 M 的公钥验证的。

    另外加密算法的安全性不是用思考具体攻击方案的方式考虑的,复合两个安全的算法也不一定达成两者安全性的“复合”。通行的做法是归约,你的算法可以看作某种安全性的 KEM 和 CPA 安全的私钥加密和签名的复合,无法推出第一个例子下的安全性。

    当然,你并没有说明你的算法期待达成何种安全性,因此我考虑的是两个人之间的对话是 authenticated channel 版本的安全性,这通常需要采用 CCA 安全的加密算法。
    ysmood
        31
    ysmood  
    OP
       2024-01-03 14:14:35 +08:00
    > 第二个问题,似乎你没有理解第一个攻击例子的场景:A 要和 B 说话,B 选择去听任何人的话,M 达成的效果是 M 不知道 A 想说什么,但是让 B 以为 M 说了 A 本来要说的话。B 是用 M 的公钥验证的。

    你都不在乎谁发给信息了如何防止中间人攻击?

    > 通行的做法是归约,你的算法可以看作某种安全性的 KEM 和 CPA 安全的私钥加密和签名的复合,无法推出第一个例子下的安全性。

    就和你说的一样,这不是 whisper 想要解决的问题,这更像是 ssl 之类的需要考虑的问题。使用 whisper 的人大大概率不会考虑中间人攻击的问题,所以 sign 是可选的否则我就设置成必选的了。
    chaoschick
        32
    chaoschick  
       2024-01-04 08:19:50 +08:00 via Android
    感觉挺多余的 这种工具的用法应该是摆在明面上的阳谋,像是现在的各种代理工具 主流都是把自己伪装成 ssl 的流量 这就是光明正大的阳谋 类似大隐隐于市
    ysmood
        33
    ysmood  
    OP
       2024-01-04 11:48:24 +08:00
    @chaoschick 你可以看看 age 这个工具 https://github.com/FiloSottile/age 被非常多的库依赖了,你可能不太能理解它的用途,但事实上用的人非常多。
    ysmood
        34
    ysmood  
    OP
       2024-01-04 12:12:37 +08:00 via Android
    @chaoschick 这种工具之所以存在就是因为现有的很多系统功能不全,且不愿意花时间改进,比如 V2EX 就没法私信,这个时候有这种工具就会方便点,你如果不用类似工具,请问 v 站里两个陌生人在不暴露自己隐私的情况下如何交换邮箱互加好友?你可能可以,但是会很麻烦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1282 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 17:54 · PVG 01:54 · LAX 09:54 · JFK 12:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.