OpenSSL的解密JSBN加密
我有麻烦在PHP解密使用RSA一些数据,我在JS已经加密:OpenSSL的解密JSBN加密
一些数据(32字节,对于RSA足够短)使用JSEncrypt加密客户端和服务器的公钥。
服务器使用其解密:
openssl_private_decrypt(BASE64_DECODE($ result_obj [ '数据']),$解密,$ pkcs_private_key);
但是,这返回44bytes,很明显这是错误的!我已经逐字节地检查过了,似乎它几乎是在解密字符串中的某些位置删除字节,但并不那么简单。
我检查了填充openssl支持,它使用PKCS#1v1.5type1,而JSEncrypt似乎使用PKCS#1v1.5type2。这可能是问题吗?我见过使用PKCS#1v1.5type2的openssl存在问题的人,因此,我们可以使用此填充,但我无法弄清楚......如何解决任何帮助!
编辑:为了更详细地说明的加密系统:
的数据进行加密的客户端是一个32字节数组。在这个例子中,我将使用数组[182,13,97,94,164,102,129,70,192,52,94,65,243,190,57,48,153,161,46,32 ,122,64,53,237,62,130,60,1,22,184,28,231]。
它被使用加密:
arr2str(arr: number[]): string {
var result = '';
for (var i = 0; i < arr.length; i++) {
result += String.fromCharCode(arr[i]);
}
return result;
}
encryptRSA(data: number[], key: string): string {
var enc = new window.JSEncrypt();
enc.setPublicKey(key);
return enc.encrypt(this.arr2str(data));
}
的关键是产生服务器的私钥的PKCS#1公钥。我们将使用关键
----- BEGIN PUBLIC KEY ----- \ nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyJ824ZiwMiCMrrHrDq1IKLwL8 \ nQWg + ZzwMprrG85k0nxEB8ZJn + s2lXhS4pOE0Nu6I9XiXjtyDbnT8kQvaWLve593v \ nDzC16wP9IKrAdmeV9CExMzKAHbFSvNTTn3TWjaKy9OnH + 7Uv/VVn63AQZXaqvY/W \ nbPVdTKn4Nx7vl + laOwIDAQAB \ n ---- -END PUBLIC KEY -----
----- BEGIN RSA私钥----- MIICXAIBAAKBgQCyJ824ZiwMiCMrrHrDq1IKLwL8QWg + ZzwMprrG85k0nxEB8ZJn + s2lXhS4pOE0Nu6I9XiXjtyDbnT8kQvaWLve593vDzC16wP9IKrAdmeV9CExMzKA HbFSvNTTn3TWjaKy9OnH + 7Uv/VVn63AQZXaqvY/WbPVdTKn4Nx7vl + laOwIDAQAB AoGASP3b4HgkBgJk/ojNR4vSsg9u1rFpp1 + ej8Rj9A1sMM4XJse151ovlVhFfx02 k7EJ7B0 + ikHjAQppbe1zgMMoPUuDOQc9VF2A2Tsf71kMagbQpNrLNiTIu6DNwzHI ivubmYBs73s2MyZmK7G8D/QRDs0qQNXdUfAKMBIUh9wQj0kCQQD5Urh18NWmW7w8 4MDFmjdalSbE9Dg38mfrlUne0KSCvwyX2zkoh/uc1eB + hqONwDkuw8VLTBgxDm + L 7jwOlmiVAkEAtu0uNEewMHi1oCIvRoS1n/UDqEHzuwFuxg + cNwAKJoN1ljqKIfqa jFLGawkyHIK2fLhP8OSQeyDi3kSoIMJzjwJAT0737FRqsdt2emsIBxNyTjcpuPby tyE921uGvwDhg9GgAOI0QWdYK2CBY94SQrIFvpF5veT7wQcVho6GviEsLQJABGj7 cC86RDDk0BOC6ERSzKRvjiLo6V1Demrt7TWHCR6qOxD2O5N7Hl7wgawbFSzhkWgw JTKdeRp13b3x/7gwaQJBAOpgGkEJKcwRFdamFYZwMGbueqkpqG/AmfNXblrOv70N CkB9YP3skoZ69 + vFr1TJXfz23lHpwQdPkRXhjlc/GLS = ----- END RSA PRIVATE KEY -----
服务器接收到此加密数据。看来,JSEncrypt b64_encodes它,所以我们必须使用
openssl_private_decrypt(BASE64_DECODE($ result_obj [ '数据']), $解密,$ pkcs_private_key)解密;
然而,我接收字节数组:
[194,182,13,97,94,194,164,102,194,129,70,195,128,52,94,65 ,195,179,194,190,57,48,194,153,194,161,46,32,122,64,53,195,173,62,194,130,60,1,22,194,184 ,28,195,167]。
也许这跟JS的arr2str函数有关。但是,我不明白怎么不使用它,因为JSEncrypt期望加密一个字符串。我认为该功能没有修改字节...
对于本示例的完整性起见,JSEncrypt返回的编码数据:
E728nXaCUUSTzuGLB5QIkodddyUMUMR0rEM5Ad7qL3SEtGJVukMjsQt7NAaRyXz1P3n2qK/iBGcuUBy2bPg5pTwk1twVZc2BzXueZYcKxxOby8AkNTgF9YMPlh1FMjD5c0UAiwcb7DnykvbsulG4h + FlxEy + 28eMTfRvjZmpq + 4 =
这是openssl_private_decrypt尝试解密的内容。
对于后代,我发现了这个问题。 事实上,它位于两个库之间的填充不兼容。
因此我设置解密模式为 “无填充” 在PHP:
openssl_private_decrypt(BASE64_DECODE($ result_obj [ '数据']), $解密,$ pkcs_private_key,OPENSSL_NO_PADDING);
而且我已经把在PHP中的JS做了去填充:
function pkcs1unpad2($b, $bits = 4096) {
$i = 0;
$n = ($bits + 7) >> 3;
$l = strlen($b);
while($i < $l && ord($b[$i]) == 0)
++$i;
if(ord($b[$i]) != 2)
return null;
++$i;
while(ord($b[$i]) != 0)
if(++$i >= $l)
return null;
$ret = "";
while(++$i < $l) {
$c = ord($b[$i]) & 255;
if($c < 128) {
$ret .= chr($c);
} elseif(($c > 191) && ($c < 224)) {
$ret .= chr((($c & 31) << 6) | (ord($b[$i+1]) & 63));
++$i;
} else {
$ret .= chr((($c & 15) << 12) | ((ord($b[$i+1]) & 63) << 6) | (ord($b[$i+2]) & 63));
$i += 2;
}
}
return $ret;
}
pcks1unpad2($解密)
是我所期望的!
base64_decode($ decrypted)会产生一个长度为6的字符串,可悲的是,它们的字节甚至不是我正在寻找的第一个字节。但也许你的意思是别的? – Ottunger
那么,我已经检查了strlen,以及解压缩(“C *”,$解密),返回一个长度为6的数组,并允许我检查每个字节的字节数 – Ottunger
我期望的字节数:[182,13,第97,94,164,102,129,70,192,52,94,65,243,190,57,48,153,161,46,32,122,64,53,237,62, 1,22,184,28,231],我收到的:[194,182,13,97,94,194,164,102,194,129,70,195,128,52,94,65,195 ,179,194,190,57,48,194,153,194,161,46,32,122,64,53,195,173,62,194,130,60,1,22,194,184,28 ,195,167] – Ottunger