首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSSL解密加密的JSBN

OpenSSL解密加密的JSBN
EN

Stack Overflow用户
提问于 2016-09-06 19:33:13
回答 1查看 239关注 0票数 2

我在PHP中解密一些使用RSA加密的JS数据时遇到了困难:

一些数据(32字节,对RSA来说足够短)是使用JSEncrypt和服务器的公钥加密客户端的。

服务器使用以下方法对其解密:

( openssl_private_decrypt(base64_decode($result_obj'data'),$decrypted,$pkcs_private_key);

但是这会返回44个字节,所以很明显这是错误的!我逐个检查了字节,看起来这几乎是在解密字符串中的某些位置删除字节的程序,但也不是那么简单。

我检查了填充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。

它使用以下方法进行加密:

代码语言:javascript
复制
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公钥。我们会用钥匙

--开始公开KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyJ824ZiwMiCMrrHrDq1IKLwL8\nQWg+ZzwMprrG85k0nxEB8ZJn+s2lXhS4pOE0Nu6I9XiXjtyDbnT8kQvaWLve593v\nDzC16wP9IKrAdmeV9CExMzKAHbFSvNTTn3TWjaKy9OnH+7Uv/VVn63AQZXaqvY/W\nbPVdTKn4Nx7vl+laOwIDAQAB\n-----END公钥 - 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= -端RSA私钥

服务器接收这些加密的数据。看来JSEncrypt b64_encodes它,所以我们必须用

( openssl_private_decrypt(base64_decode($result_obj'data'),$decrypted,$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试图解密的内容。

EN

回答 1

Stack Overflow用户

发布于 2016-09-07 06:02:12

为了子孙后代,我发现了这个问题。实际上,它存在于两个库之间不兼容的填充中。

因此,我将PHP中的解密模式设置为“无填充”:

( openssl_private_decrypt(base64_decode($result_obj'data'),$decrypted,$pkcs_private_key,OPENSSL_NO_PADDING);

我在PHP中使用JS完成了打开填充的操作:

代码语言:javascript
复制
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($decrypted)

这正是我所期望的!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39356537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档