首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
V2EX  ›  问与答

确认下 RSA 加密签名的一些疑惑

  •  
  •   coolair · 37 天前 · 652 次点击
    这是一个创建于 37 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在的需求是:把 public key 给客户机,服务器存 private key,服务器给客户机发消息,客户机响应后执行操作。
    所以,我的想法是加密不行,加密是用 public key 加密,传给服务器,服务器用 private key 解密。
    所以用签名,把消息(明文)和签名(用 private key 签名)发给客户机,客户机接收后用 public key 解签,成功,执行消息中的指令操作,解签失败则不执行。


    另外:
    1 )如果用签名的话,是不是消息被截获了,就被知道了?因为是明文的。
    2 )用 private key 签名,用 private key 和 public key 都可以解签成功。
    3 )用 private key 加密的数据,只能用 private key 解密,public key 不能解密。
    4 )用 public key 加密的数据只能用 private key 解密,不能用 public key 解密。


    我的以上说法正确吗???

    以上测试代码来自于:
    https://pycryptodome.readthedocs.io/en/latest/src/signature/pkcs1_pss.html
    https://pycryptodome.readthedocs.io/en/latest/src/examples.html
    13 回复  |  直到 2019-08-10 17:27:56 +08:00
        1
    HaoLan   37 天前 via Android
    设置两对 keys 不就可以了。
    客户端服务端一对,服务端客户端一对
        2
    shansing   37 天前
    不是密码学专业,以我有限的知识先帮楼主消灭零回复。(未必正确,欢迎指正。)

    楼主为什么说加密不行呢?加密未必是用公钥加密。公钥和私钥在数学上是对等的:可以用公钥加密,只有私钥能解密,也可以用私钥加密而只有公钥能解密。也就是 2、3 错误,4 正确。只是,一些 RSA 的实现,会在私钥文件中同时存储公钥(和私钥)。

    如果想签名的的话,用明文暴露消息肯定是有被窃听的可能,也就是 1 正确。签名的意义在于校验消息完整性,防止消息被篡改。而如果你想防止窃听,需要将消息加密。既对消息加密,又认证消息的做法有几种(根据顺序区分),也就是 E&M、MtE、EtM。据说最后一种是最好的。AES 的 GCM 就可实现 EtM。(加密消息不太可能会用 RSA 这种非对称加密方法,因为慢,取而代之的是诸如 AES 的对称加密算法。)

    呃,这样想来,不是很明白楼主这个需求是什么,为什么最初想用非对称加密算法加密消息。
        3
    lagoon   37 天前
    RSA 1 号公钥私钥。
        4
    lagoon   37 天前
    RSA 1 号公钥私钥。
    RSA 2 号公钥私钥。
    服务器持有 1 号私钥,2 号公钥。
    客户端持有 2 号私钥,1 号公钥。
    我错了,其实我没听到题主的问题。
        5
    Xbluer   37 天前
    1、4 正确,2、3 错误。
        6
    napsterwu   37 天前 via iPhone
    两对 key
    不过两对 key 共四把密钥,攻击者自然可以看到三把
        7
    gimp   37 天前   ♥ 1
    严格来说,RSA 算法中公钥加密和数字签名正好是完全相反的关系。

    用私钥加密相当于生成签名,用公钥解密相当于验证签名。
    同样加密来讲,公钥加密后,只有对应的私钥可以解密

    1 )是的
    2 )私钥签名后,只有配对的公钥能够进行验证,知道私钥可以生成公钥,反之不行
    3 )同 2 )
    4 )是的


    其实明文加解密你可以用 AES,速度比非对称加密快很多。

    RSA 可以用来分发 AES 加密用的 key

    如果你想要确保消息是来自合法客户端的,那么生成一对密钥,客户端持有自己的私钥,服务端保存这个客户端的公钥(参考 Github 推送代码时,先添加自己的公钥到服务器,以便确认用户身份)

    如果你想要确保指令消息时来自服务器,那么再生成一对密钥,客户端持有公钥,服务端自己保存私钥,服务器发送消息用私钥加密,也就是签名,公钥能解密就说明来自服务器

    用 AES 加密消息,那么这个 key 怎么分发是个问题,这就可以借助于 RSA 来分发 key,服务器用客户端的公钥来对 key 进行加密,客户端用私钥进行解密,获取里面的 key。通信的时候都用 key 进行加密解密

    客户端如何将公钥发送给服务端需要通过 HTTPS 传输防止中间人攻击
        8
    Sylv   37 天前 via iPhone
    直接走 HTTPS + Certificate Pinning 就可以了,没必要自己造轮子。
        9
    ryd994   37 天前 via Android   ♥ 1
    加密永远是持有公钥的发送,持有私钥的解密
    签名永远是持有私钥的签名,持有公钥的解密

    如果你要实现双向加密通信,你有两种选择:
    1. 学普通 HTTPS 网站的做法,RSA 仅作签名用于验证服务器身份避免中间人攻击。双方协商一个对称密钥,实际通讯由对称密钥加密。然后用账号密码等方式再验证服务器身份。
    1.5 稍高级的 HTTPS 网站可以使用客户端证书直接实现双向验证。网银插件就是这样。U 盾本质上也是,但是基于硬件智能卡,所以更安全。

    2.学 PGP/GPG,想给谁发消息就先想办法取得接收方的加密公钥。至于怎么验证公钥避免中间人工具,就只能靠其他可信信道。反正假设你已经取得并验证过公钥。

    @shansing 实际上不对等,因为公钥的其中一个因子一般是固定为 65537,因此只要知道私钥,就能简单推出公钥。
        10
    shansing   37 天前
    @ryd994 谢谢。

    我刚也查了 https://www.v2ex.com/t/144641 等网页,发现现实中私钥是容易推导出公钥的。
        11
    AlvaIM   37 天前   ♥ 2
    非对称加密的话, 均是 公钥加密, 私钥解密, 私钥签名, 公钥验签, 把握住这个 4x4 的四字箴言就不会搞错了
        12
    jaskle   37 天前 via Android
    私钥能够导出公钥,所以私钥加密私钥也是能解开的,这也是为什么要分为公开私有。
        13
    AlvaIM   37 天前
    SSL/TLS 现在推荐使用类似 secp256k1 这类基于椭圆曲线的非对称密钥对系统就是因为 EC 系统通过 ECDH 来实现零知识证明的密钥分发 是天然抵御中间人攻击的。简单的来说, 假设有 2 个人,Alice 和 Bob, 各持有一个密钥对,Alice 的公钥给 Bob,Bob 的公钥给 Alice, 现在互相要发消息给对方, 假设 Alice 要发给 Bob, 那么 Alice 只需要用自己的私钥和 Bob 的公钥就能计算出一个密钥, 用这个密钥通过对称加密比如 AES 加密数据后发给 Bob,Bob 获取后, 通过自己的私钥和 Alice 的公钥就能同样计算出和 Alice 一样的密钥, 就能解开密文得到原始数据了。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1645 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 16:29 · PVG 00:29 · LAX 09:29 · JFK 12:29
    ♥ Do have faith in what you're doing.