对方给的为 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
Aruforce 2020-08-13 09:58:53 +08:00 1
php RSA 密钥是 PKCS7 填充 Java 是 PKCS8 。。。你需要用 openssl 将对面给的做个格式转换
|
3
kangsgo OP @Aruforce 我转换了但是加密不了这么长的,我在网上看 512bit 最多也只支持 53 位加密,不知道 java 怎么弄的
|
5
linnil 2020-08-13 10:25:21 +08:00
加密的时候是分块的,不足位数时需要填充,有不同的填充方式,你需要看下 java 代码,看其使用的填充方式。openssl 使用的是 0 做填充的,至于 php,我不太了解。
|
7
wangritian 2020-08-13 10:39:58 +08:00
和 java 对接过加密,就是 padding 策略不一致
|
8
linnil 2020-08-13 10:47:53 +08:00
@kangsgo 过长。。。有过长之说?,用 512 我就只能加密 512 位之内的数据长度?那有啥用。
许多经典密码会将明文排列成特定的形状(如:正方形、长方形等),而如果明文不能完全符合形状,就需要添加字母来填满形状。你可以看下[Padding_]( https://en.wikipedia.org/wiki/Padding_(cryptography)) |
9
GM 2020-08-13 11:00:03 +08:00
@linnil
有啥用? aes 128 一次也只能加密 128bit 的数据啊!那为啥大家是怎么用来加密大块数据? 答案是:当然是切成小块分别加密然后拼接了。 另外: RSA 本身一般不用来做实际传输的数据加密的,因为实在太慢了,一般来说只用于秘钥加密。 做法如下: 随机生成一串 AES 秘钥,然后用这个 AES 秘钥来来给大块数据加密,最后用 RSA 把这个 AES 秘钥再加密一次,拼接到刚才刚加密的密文前面或者后面。 |
11
neighbads 2020-08-13 11:27:20 +08:00 1
java 也没有直接能用 rsa 密钥加密超过模长数据的现成包吧。楼上几位说的用 rsa 分组加密根本没有这样用的,对于 rsa 的 pad 也不是用在这种场景的。对于大数据都是先用对称,然后在用非对称
建议是直接问对方截取 java 代码加密的流程或者调用的方法。可能比在这里问要快一些。。 |
13
qwerthhusn 2020-08-13 11:47:10 +08:00 1
lz,你上面贴的 key,公钥和私钥都不匹配
公钥是 ANSI,1024 位的,也不是你说的 512 位 私钥格式是 PKCS8,Base64 编码还用了 URLSafe 的编码, 所有的+变成了-,所有的 /变成了_,最后私钥解出来也是 1024 位的,还和公钥不匹配。。 |
14
qwerthhusn 2020-08-13 11:55:26 +08:00
公钥 Modulus=e80e5bb2f8cd05a7041b08f3e962e20258358e187a6e692b252cdf297a016bac83551a367b1e74c7a8a88feddb4ac3e470b778dd73932c371ae74c72935cc8d5e0f16125f9a9edc421ab80a0072a12f8d406ee131c4921363120395b4983e2a5ceae040a4fa05e113103464d0f8ca03948b7614240ee34c31115f7e0b9fb1de1
公钥长度=1024 私钥 Modulus=9ac406c7730e307615245e95c15eab05c27f19c7d6f94d60b4e8710b68857fabdeaaa106f73c2d38f013d88f3684e4b2456ec21c383f37400a163efeec9fe795 私钥长度=512 说错了,私钥是 512 的,公钥是 1024 的 |
15
qwerthhusn 2020-08-13 11:57:04 +08:00
在你不知道各种 padding 的时候,就让对方提供一个密钥对和一个加密输出,然后自己再去测试是哪种 Padding,有没有 ECB
|
16
kangsgo OP @qwerthhusn
谢谢,对方发给我的我没有测试。 之前试了他们发的内容是可以加密短的内容的。通过 v2 的大神琢磨出来+变成了-,所有的 /变成了_,并且要用=补齐私钥到 460 位, 可以解密。我要被弄晕了~。~我自己测试一下他发给我的。十分抱歉! |
17
supermoonie 2020-08-13 12:13:46 +08:00 via iPhone 1
推荐楼主看下 Java 加密与解密的艺术 这本书,加解密这种东西你听别人讲,自己不去了解,除了懵逼,最后啥都不剩
|
18
kangsgo OP @supermoonie 非常感谢,我弃坑了
|
20
Phariel 2020-08-13 13:47:30 +08:00 via iPhone
从入门到跑路😂
|
21
iyaozhen 2020-08-13 13:47:56 +08:00
就是各个语言细节上不一样。你要是 aes 的我可以给你一个,各大语言都有 demo
rsa 的没弄过 |
22
fiypig 2020-08-13 13:49:39 +08:00
rsa 需要分段加解密
|
23
chenzheyu 2020-08-13 13:49:43 +08:00
这个我一般都是用 laravel 自带的加密搞定的
|
24
Evilk 2020-08-13 15:07:10 +08:00
所以最后,怎么解决的?
|
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 公钥加密方法,先将要加密的字段分块,然后加密就可以了 |