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

这个操作怎么实现:使用 rsa 私钥加密数据,然后 rsa 公钥解密(并不是数字签名认证,最好是 golang 实现)

  •  
  •   z0ne · 2019-05-10 22:08:13 +08:00 · 4411 次点击
    这是一个创建于 1784 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言  ·  2019-05-11 01:12:13 +08:00

    我想达到的效果:

    1. 我用私钥加密一段密文
    2. 所有有公钥的用户都可以解密(并不是纯粹的验证是否是私钥加密的)不考虑这部分安全问题(就是让“不安全”使得这段密文共享,但是无法篡改)

    用rsa应该能实现吧?

    第 2 条附言  ·  2019-05-11 10:01:58 +08:00

    已经解决了,感谢大家提供的建议和参考!

    54 条回复    2019-05-11 11:02:24 +08:00
    z0ne
        1
    z0ne  
    OP
       2019-05-10 22:11:05 +08:00
    我对算法什么的不熟,好像是无法使用 rsa 公钥进行解密的(只能加密)
    那么我要是想达到这个操作,怎么实现比较合适呢?
    allenforrest
        2
    allenforrest  
       2019-05-10 22:16:24 +08:00
    何出此言?
    z0ne
        3
    z0ne  
    OP
       2019-05-10 22:19:14 +08:00
    @allenforrest
    我是想实现如下功能:
    1. 我用“私钥”加密一段数据,发送给用户,当成程序的认证码
    2. 程序中保存着“公钥”,这个”公钥“只能用来解密这段数据,解密后进行判断认证是否合法
    期间这段认证码没有私钥是无法伪造生成的

    用 rsa 算法能否实现呢?
    jiafaner
        4
    jiafaner  
       2019-05-10 22:19:22 +08:00
    反了吧?
    ThirdFlame
        5
    ThirdFlame  
       2019-05-10 22:20:32 +08:00   ❤️ 1
    所谓的加密和解密只是相对的。
    数字签名认证,就是你使用你的私钥加密哈希值,传送给对方。 对方拿你的公钥解密后,得到哈希值,与传送内容的哈希值值进行比较。确定是不是你发送的。 你说有没有用到公钥解密。
    z0ne
        6
    z0ne  
    OP
       2019-05-10 22:20:49 +08:00
    @jiafaner 需求没反,但代码实现可能反了
    z0ne
        7
    z0ne  
    OP
       2019-05-10 22:21:54 +08:00
    @ThirdFlame
    我是 想不止达到数字签名认证对比的功能,而是能读取解密出这个“签名”的数据~
    luban
        8
    luban  
       2019-05-10 22:22:07 +08:00 via iPhone   ❤️ 1
    rsa 是可以公钥加密私钥解密,也可以私钥加密公钥解密
    luban
        9
    luban  
       2019-05-10 22:22:48 +08:00 via iPhone
    java 网上有很多例子,golang 没用过
    kalista
        10
    kalista  
       2019-05-10 22:52:38 +08:00
    网上挺多 go 调用 rsa 的,官方有 crypto 库
    ThirdFlame
        11
    ThirdFlame  
       2019-05-10 23:15:03 +08:00
    @z0ne 大哥 你把哈希值 当做明文,这不就是 私钥加密,公钥解密么
    zealot0630
        12
    zealot0630  
       2019-05-10 23:24:58 +08:00 via Android
    公钥是“公开的”,你这种方法毫无安全可言。

    公开并不是说你不泄漏就不公开了,而是整个加密体系都围着公钥是公开的这个假设展开的,举例来说,公钥不会放在 sensitive memory 里面,比如你的程序 core dump 了,那么私钥是不会出现在 core dump 中,但是公钥就会。在使用公钥时候,不会考虑各种攻击,比如 time attack,等等因素,都会导致你的公钥非常容易泄露。

    总而言之,不要这样做!
    zealot0630
        13
    zealot0630  
       2019-05-10 23:27:53 +08:00 via Android
    看了你后面的描述,你需要的是签名功能,证明代码与数据的来源可靠,这是 RSA 的标准用法,google rsa sign 就可以了。加密在这里毫无意义。
    zealot0630
        14
    zealot0630  
       2019-05-10 23:30:11 +08:00 via Android
    如果你不想让你的程序明文在互联网上传输,请使用 TLS
    AlphaTr
        15
    AlphaTr  
       2019-05-10 23:34:10 +08:00 via iPhone
    你这功能叫签名和验签吧……
    wangsongyan
        16
    wangsongyan  
       2019-05-10 23:37:20 +08:00 via iPhone
    license ?
    z0ne
        17
    z0ne  
    OP
       2019-05-11 00:28:51 +08:00
    @zealot0630
    不是数字证书签名
    我的意思是:使用私玥加密,然后可以且只能用公玥解密,那么我只需要发布公玥和加密后的数据(公玥可以解密这个数据,而不是仅仅只是校验),而且这部分的数据都不可篡改
    z0ne
        18
    z0ne  
    OP
       2019-05-11 00:30:14 +08:00
    @zealot0630
    好像 RSA 只能“单向”的加密,也就是使用公玥解密,然后只能用私玥解开,但是我的需求是反的,想用私玥加密,只能用公玥解开
    ahhui
        19
    ahhui  
       2019-05-11 00:35:34 +08:00 via iPhone
    @z0ne 你需要两对公 /私钥
    z0ne
        20
    z0ne  
    OP
       2019-05-11 00:43:22 +08:00
    @ahhui 您的意思是创建两个私钥,然后再生成两个公钥是吗?那怎么利用呢
    xyfan
        21
    xyfan  
       2019-05-11 00:47:37 +08:00 via Android   ❤️ 1
    我猜你想用 rsa 实现 license 的功能。感觉有点问题,公钥是公开的,默认所有人都能获取(即使写进程序里),所以你对数据的加密本质上没有用,因为所有人都可以用公钥进行解密,真正起作用的只有签名。应该把加密和签名分开,加密用其他算法,脱离签名用的公 /私钥对。
    lzxgh621
        22
    lzxgh621  
       2019-05-11 00:50:07 +08:00 via iPhone   ❤️ 1
    不考虑安全的前提下,程序里的公私钥换一下位置就好。
    lzxgh621
        23
    lzxgh621  
       2019-05-11 00:52:28 +08:00 via iPhone
    Bryan0Z
        24
    Bryan0Z  
       2019-05-11 01:00:21 +08:00 via Android
    看了眼你的需求,你要实现的功能不就是数字签名吗…一大堆库可以挑。RSA 私钥和公钥都可以用来加密,用私钥叫做签名,用公钥就真的是加密了
    z0ne
        25
    z0ne  
    OP
       2019-05-11 01:05:21 +08:00
    @xyfan
    是的,我的本意就是想让所有带有公钥的程序都能够解密出我加密的信息(只能解密,而且这段信息只有我能加密,解密后的数据还做了一层校验,理论上来说没有私钥就无法伪造)
    z0ne
        26
    z0ne  
    OP
       2019-05-11 01:13:19 +08:00
    @lzxgh621 感谢,我搜索了一圈没搜到之前 v2 的帖子,可能是关键词没用好。 我再研究研究
    Zzdex
        27
    Zzdex  
       2019-05-11 01:27:42 +08:00 via iPhone
    golang 官方库
    Zzdex
        28
    Zzdex  
       2019-05-11 01:27:51 +08:00 via iPhone
    rrfeng
        29
    rrfeng  
       2019-05-11 01:32:33 +08:00
    没问题,可以,官方库就能完成,自带 example
    zhy0216
        30
    zhy0216  
       2019-05-11 01:35:52 +08:00
    @z0ne 加密的信息里包含私钥的公钥 公钥解密后检验和那段公钥是否匹配
    zsj950618
        31
    zsj950618  
       2019-05-11 01:42:02 +08:00
    官方库可以实现私钥加密,但没有实现公钥解密。参考官方库里的实现自己写了一下,见

    https://play.golang.org/p/CR2z1RNlagX
    Sylv
        32
    Sylv  
       2019-05-11 03:24:26 +08:00 via iPhone
    如果你是为了客户端验证的话,我认为最简单的方法是程序内嵌锁定证书,然后直接走 HTTPS 跟服务器验证,这样就能做到客户端和服务器之间的交流是加密且无法篡改伪造的了,没必要自己造轮子。
    RecursiveG
        33
    RecursiveG  
       2019-05-11 03:49:45 +08:00 via Android
    非密码学专家建议用别人造好的轮子。https://en.wikipedia.org/wiki/Authenticated_encryption
    hearfish
        34
    hearfish  
       2019-05-11 03:57:43 +08:00
    这不就是数字签名么

    公钥和私钥从数学上来讲是可以互换的(用一个加密以后可以用另一个解密)
    silentstorm
        35
    silentstorm  
       2019-05-11 07:48:20 +08:00 via Android
    你搞反了吧,这是签名功能
    hhhsuan
        36
    hhhsuan  
       2019-05-11 08:04:53 +08:00 via Android
    这不就是最基本的 RSA 加解密功能吗?随便找个 RSA 的库就能做啊。没看出你的需求有什么特殊的地方。
    chinvo
        37
    chinvo  
       2019-05-11 08:13:37 +08:00 via iPhone   ❤️ 1
    防止伪造应该用签名,客户端收到的数据包含明文原文和签名,然后对签名进行校验
    AlphaTr
        38
    AlphaTr  
       2019-05-11 08:18:12 +08:00 via iPhone   ❤️ 1
    可是还是一个数字签名,既然不考虑安全性,这部分数据就明文传输,还是用数字签名保证不被篡改就可以了
    fangxing204
        39
    fangxing204  
       2019-05-11 08:27:17 +08:00 via Android
    公钥是公开的, 用公开的密码去解密,那这个加密有什么意义?
    zhujinliang
        40
    zhujinliang  
       2019-05-11 08:55:45 +08:00 via iPhone
    可以参考 crypto/rsa 包的 EncryptOAEP 和 DecryptOAEP 两个例子
    zhujinliang
        41
    zhujinliang  
       2019-05-11 08:58:33 +08:00 via iPhone
    没看明白楼主是想加密还是签名,签名的话是 SignPKCS1v15 和 VerifyPKCS1v15 两个例子
    lzvezr
        42
    lzvezr  
       2019-05-11 09:07:44 +08:00 via iPhone
    根据 RSA 的原理,完全可以"私钥"加密"公钥"解密,公钥私钥只是以使用方式区分命名而已,你用哪个加密哪个就是公钥
    ruimz
        43
    ruimz  
       2019-05-11 09:11:46 +08:00 via Android
    楼主提出想法 A,但楼上很多人都在用“为什么 B 可行”来反驳“ A 为什么不可行”。
    既然安全性是数学保证的,没什么不可以的
    mengyaoss77
        44
    mengyaoss77  
       2019-05-11 09:11:57 +08:00 via Android
    你自己用公钥加密,把私钥分发一下不就行了。
    maggch
        45
    maggch  
       2019-05-11 09:20:54 +08:00 via Android
    公钥私钥互为模 n 下的逆元,交换一下完全没问题。
    mcfog
        46
    mcfog  
       2019-05-11 09:38:56 +08:00 via Android
    关键是你描述了半天签名的流程然后固执地说这不是签名我不要签名我就要加密

    不是说数据变成一串 base64 就叫加密了的
    opengps
        47
    opengps  
       2019-05-11 09:42:58 +08:00
    概念有点乱:
    公钥私钥,取决于你公开那个私有哪个
    解密加密,你自己选取其中一个
    z0ne
        48
    z0ne  
    OP
       2019-05-11 09:57:13 +08:00
    @chinvo 明白您的意思了,我以为单纯的认证没法做到数据获取,没想到直接明文+认证也可以达到这个效果,感谢!
    z0ne
        49
    z0ne  
    OP
       2019-05-11 10:00:51 +08:00
    @mcfog 是的,也许就是“签名”的效果吧。
    但是我并不想“明文”存储这个“签名”,而是想用公钥解密这个“明文“,然后再读取出”签名“的原始数据

    基础不太牢,这方面不在行,见笑啦~
    mcfog
        50
    mcfog  
       2019-05-11 10:48:41 +08:00 via Android   ❤️ 1
    @z0ne 与其打这么多引号,不如先去查查找些术语分别是什么含义,不理解术语的含义连准确地表达你的疑问都做不到,所以大家只能先猜你懂啥(但说法不对)不懂啥然后尝试给一些答案出来

    哦对,顺便这楼里也有很多人和你差不多状态,鸡同鸭讲
    mcfog
        51
    mcfog  
       2019-05-11 10:49:16 +08:00 via Android
    @mcfog 找些 => 这些
    reself
        52
    reself  
       2019-05-11 11:00:06 +08:00 via Android
    这不就是签名么
    reself
        53
    reself  
       2019-05-11 11:01:22 +08:00 via Android
    基础差又不愿去找资料学习
    reself
        54
    reself  
       2019-05-11 11:02:24 +08:00 via Android
    别人给出了建议又不虚心去学习
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3231 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 14:20 · PVG 22:20 · LAX 07:20 · JFK 10:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.