V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kangsgo
V2EX  ›  PHP

请问一个 rsa 加密问题

  •  
  •   kangsgo · 2020-08-13 09:47:30 +08:00 · 3467 次点击
    这是一个创建于 1550 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对方给的为 rsa 512bit 加密,文件如下(密钥只是做演示用,实际上不会用它,谢谢各位关心):

    公钥:

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoDluy+M0FpwQbCPPpYuICWDWOGHpuaSslLN8pegFrrINVGjZ7HnTHqKiP7dtKw+Rwt3jdc5MsNxrnTHKTXMjV4PFhJfmp7cQhq4CgByoS+NQG7hMcSSE2MSA5W0mD4qXOrgQKT6BeETEDRk0PjKA5SLdhQkDuNMMRFffgufsd4QIDAQAB
    

    私钥:

    MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmsQGx3MOMHYVJF6VwV6rBcJ_GcfW-U1gtOhxC2iFf6veqqEG9zwtOPAT2I82hOSyRW7CHDg_N0AKFj7-7J_nlQIDAQABAkEAkMYy-Tx914N-f4kjWcIvBbJNp1YzmP5zKogNx3g8-ZHb7PmvLL7MGX-yeaH2WDJbAcisYRBR-QMKSTLK0wxbuQIhAOFxGiEeIynPPlP8hNNhQpkfqQDEdwiPrsReDddz1IqHAiEAr75xho4Z1ivaGq93bvskWA0C8CEXR7x73skh_vv1eAMCIEoHyw3PCLsFDDGmPbPwP19rLyNKYNBV5o0jWaZDqirnAiBOF_BWfFqaww2-Ae6ukEbMIawGjI3NwMHCc9n5dnjThQIgICR7g2y_DLFeacC5Kx99dSDh-d5ZcO-vQmMAMp6TS2A
    

    公钥加密——私钥解密 明文:

    {"iccid":"8986112022503532929","nickName":"aaa","userPhone":"17336606861","idCard":"430204199101172111"}
    

    密文:

    khls5onpTAZ9ilpcQgg4ACX22BSdFmMW_rSlXQmbrso20jVDpq5S0V8WhmibonkfRun0H3gVIeOnD5DHzcIJCXVKpYAUeNX-om38Lh7vHJAGzpfbx0uKV_nK5Wqe6rocAK72sxpOb4NAAtlep_tKPE8ZDgKSlAs5wJWH3CMpzP4
    

    我用的 php 这样写的:

        public function publicEncrypt($data = '') {
            if (!is_string($data)) {
                return null;
            }
            return openssl_public_encrypt($data, $encrypted, $this->public_key) ? base64_encode($encrypted) : null;
        }
    

    返回的为空,我在在线网站上用 rsa 512bit 貌似也不行,麻烦各位帮我看一下他是怎么加密的,他是用的 java,php 有什么办法没,谢谢

    第 1 条附言  ·  2020-08-13 12:55:17 +08:00
    已弃坑!
    26 条回复    2020-08-14 10:28:42 +08:00
    Aruforce
        1
    Aruforce  
       2020-08-13 09:58:53 +08:00   ❤️ 1
    php RSA 密钥是 PKCS7 填充 Java 是 PKCS8 。。。你需要用 openssl 将对面给的做个格式转换
    Aruforce
        2
    Aruforce  
       2020-08-13 09:59:33 +08:00
    @Aruforce 至于怎么转 你看下 openssl 的 命令吧
    kangsgo
        3
    kangsgo  
    OP
       2020-08-13 10:15:31 +08:00
    @Aruforce 我转换了但是加密不了这么长的,我在网上看 512bit 最多也只支持 53 位加密,不知道 java 怎么弄的
    gz911122
        4
    gz911122  
       2020-08-13 10:24:21 +08:00
    @kangsgo
    微信支付宝 支付我记得都有测试工具你可以试下
    linnil
        5
    linnil  
       2020-08-13 10:25:21 +08:00
    加密的时候是分块的,不足位数时需要填充,有不同的填充方式,你需要看下 java 代码,看其使用的填充方式。openssl 使用的是 0 做填充的,至于 php,我不太了解。
    kangsgo
        6
    kangsgo  
    OP
       2020-08-13 10:35:10 +08:00
    @linnil 就是如果加密文件过长,就一段一段加密的么
    wangritian
        7
    wangritian  
       2020-08-13 10:39:58 +08:00
    和 java 对接过加密,就是 padding 策略不一致
    linnil
        8
    linnil  
       2020-08-13 10:47:53 +08:00
    @kangsgo 过长。。。有过长之说?,用 512 我就只能加密 512 位之内的数据长度?那有啥用。
    许多经典密码会将明文排列成特定的形状(如:正方形、长方形等),而如果明文不能完全符合形状,就需要添加字母来填满形状。你可以看下[Padding_]( https://en.wikipedia.org/wiki/Padding_(cryptography))
    GM
        9
    GM  
       2020-08-13 11:00:03 +08:00
    @linnil

    有啥用? aes 128 一次也只能加密 128bit 的数据啊!那为啥大家是怎么用来加密大块数据?
    答案是:当然是切成小块分别加密然后拼接了。

    另外:
    RSA 本身一般不用来做实际传输的数据加密的,因为实在太慢了,一般来说只用于秘钥加密。

    做法如下:

    随机生成一串 AES 秘钥,然后用这个 AES 秘钥来来给大块数据加密,最后用 RSA 把这个 AES 秘钥再加密一次,拼接到刚才刚加密的密文前面或者后面。
    GM
        10
    GM  
       2020-08-13 11:01:09 +08:00
    @linnil 理解错误、回复错了,见谅~~~
    neighbads
        11
    neighbads  
       2020-08-13 11:27:20 +08:00   ❤️ 1
    java 也没有直接能用 rsa 密钥加密超过模长数据的现成包吧。楼上几位说的用 rsa 分组加密根本没有这样用的,对于 rsa 的 pad 也不是用在这种场景的。对于大数据都是先用对称,然后在用非对称

    建议是直接问对方截取 java 代码加密的流程或者调用的方法。可能比在这里问要快一些。。
    kangsgo
        12
    kangsgo  
    OP
       2020-08-13 11:42:25 +08:00
    @neighbads
    @linnil
    @GM
    好的,谢谢各位
    qwerthhusn
        13
    qwerthhusn  
       2020-08-13 11:47:10 +08:00   ❤️ 1
    lz,你上面贴的 key,公钥和私钥都不匹配

    公钥是 ANSI,1024 位的,也不是你说的 512 位
    私钥格式是 PKCS8,Base64 编码还用了 URLSafe 的编码, 所有的+变成了-,所有的 /变成了_,最后私钥解出来也是 1024 位的,还和公钥不匹配。。
    qwerthhusn
        14
    qwerthhusn  
       2020-08-13 11:55:26 +08:00
    公钥 Modulus=e80e5bb2f8cd05a7041b08f3e962e20258358e187a6e692b252cdf297a016bac83551a367b1e74c7a8a88feddb4ac3e470b778dd73932c371ae74c72935cc8d5e0f16125f9a9edc421ab80a0072a12f8d406ee131c4921363120395b4983e2a5ceae040a4fa05e113103464d0f8ca03948b7614240ee34c31115f7e0b9fb1de1
    公钥长度=1024
    私钥 Modulus=9ac406c7730e307615245e95c15eab05c27f19c7d6f94d60b4e8710b68857fabdeaaa106f73c2d38f013d88f3684e4b2456ec21c383f37400a163efeec9fe795
    私钥长度=512

    说错了,私钥是 512 的,公钥是 1024 的
    qwerthhusn
        15
    qwerthhusn  
       2020-08-13 11:57:04 +08:00
    在你不知道各种 padding 的时候,就让对方提供一个密钥对和一个加密输出,然后自己再去测试是哪种 Padding,有没有 ECB
    kangsgo
        16
    kangsgo  
    OP
       2020-08-13 11:57:17 +08:00
    @qwerthhusn
    谢谢,对方发给我的我没有测试。
    之前试了他们发的内容是可以加密短的内容的。通过 v2 的大神琢磨出来+变成了-,所有的 /变成了_,并且要用=补齐私钥到 460 位,
    可以解密。我要被弄晕了~。~我自己测试一下他发给我的。十分抱歉!
    supermoonie
        17
    supermoonie  
       2020-08-13 12:13:46 +08:00 via iPhone   ❤️ 1
    推荐楼主看下 Java 加密与解密的艺术 这本书,加解密这种东西你听别人讲,自己不去了解,除了懵逼,最后啥都不剩
    kangsgo
        18
    kangsgo  
    OP
       2020-08-13 12:54:59 +08:00
    @supermoonie 非常感谢,我弃坑了
    qistchan
        19
    qistchan  
       2020-08-13 13:45:23 +08:00
    @kangsgo #18 目睹了从入门到弃坑
    Phariel
        20
    Phariel  
       2020-08-13 13:47:30 +08:00 via iPhone
    从入门到跑路😂
    iyaozhen
        21
    iyaozhen  
       2020-08-13 13:47:56 +08:00
    就是各个语言细节上不一样。你要是 aes 的我可以给你一个,各大语言都有 demo
    rsa 的没弄过
    fiypig
        22
    fiypig  
       2020-08-13 13:49:39 +08:00
    rsa 需要分段加解密
    chenzheyu
        23
    chenzheyu  
       2020-08-13 13:49:43 +08:00
    这个我一般都是用 laravel 自带的加密搞定的
    Evilk
        24
    Evilk  
       2020-08-13 15:07:10 +08:00
    所以最后,怎么解决的?
    kangsgo
        25
    kangsgo  
    OP
       2020-08-13 19:37:58 +08:00
    @Evilk 直接和对方说做不了,疯狂说抱歉对不起,就没弄了
    cbasil
        26
    cbasil  
       2020-08-14 10:28:42 +08:00   ❤️ 1
    public static function encryptByPublicKey($data, $key)
    {
    $key = self::get_public_key($key);
    if (!$key) return false;
    $crypto = '';
    $originalData = str_split($data,117);
    foreach ($originalData as $chunk) {
    openssl_public_encrypt($chunk, $encryptData, $key);
    $crypto .= $encryptData;
    }
    return base64_encode($crypto);
    }
    贴一个自用的 rsa 公钥加密方法,先将要加密的字段分块,然后加密就可以了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2744 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 08:51 · PVG 16:51 · LAX 00:51 · JFK 03:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.