openssl_pkey_get_details($ res)不返回公共指数 [英] openssl_pkey_get_details($res) returns no public exponent

查看:167
本文介绍了openssl_pkey_get_details($ res)不返回公共指数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此示例进行javascript加密,使用生成的密钥与php openssl 库,但 $ details = openssl_pkey_get_details($ resource)正在返回没有公开指数( $ details ['rsa'] ['e'] )。

I'm using this example for javascript encryption using a key generated with the php openssl library, but $details = openssl_pkey_get_details($resource) is returning no public exponent ($details['rsa']['e']).

这是我如何生成它:

function genKeys() {
    // Create the keypair
    $res=openssl_pkey_new();
    // Get private key
    $pass = bin2hex(mcrypt_create_iv(100, MCRYPT_DEV_URANDOM));
    openssl_pkey_export($res, $pk, $pass);

    $details = openssl_pkey_get_details($res);
    print_r($details);
    $details = array('n'=>$details['rsa']['n'],'e'=>$details['rsa']['e']);

    return array($pk,$details,$pass);
}
function to_hex($data)
{
    return strtoupper(bin2hex($data));
}
$details = genKeys()[1];

当我使用 print_r 打印出 $ details 数组,我得到:

When I use print_r to print out the $details array, I get:

Array
(
    [bits] => 2048
    [key] => -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt+S0ZxgyQ7BPcmz/JEa7
yEhcKDZTE9TgOF/9cW1w+quFvC43daYmyRpT3asYOm7YPGCmaQ7hUx9XKUUlEdXz
Zr1uvvDyFZdtS45+4nQ5DOI20mZoUHGV82rAMmvf5vote/JJu8Gt01ZUARfsMl+K
DtwpVDHN6LGPBOW8l8abktk1tL/oiwLSVrO2cM/IgBZETDkQpUaZxZx3yUcueEQ+
BFrtS3IYaEny938daQzElNdCaip0f68Ig0gOTPzwkzDOgyOhyjFRxx4aisGzIlXu
TFkqzIz7oC3JysgS5EhlwmsEIAelbZWpgc17HK2aWIzqlT99hB+kKv2fauxH/fgT
nQIDAQAB
-----END PUBLIC KEY-----

    [rsa] => Array
        (
            [n] => ���g2C�Orl�$F��H\(6S��8_�qmp����.7u�&�Sݫ:n�<`�i�SW)E%��f�n����mK�~�t9�6�fhPq��j�2k���-{�I����VT�2_��)T1�豏弗ƛ��5�����V��p�ȀDL9�F�Ŝw�G.xD>Z�KrhI��iĔ�Bj*t��HL���0΃#��1Q����"U�LY*̌��-����He�k �m����{��X���?}��*��j�G���
            [e] => 
            [d] => ~����G�P�t���@��5��z�nEk�m���    qИ���i�k�%�ĨS���{/�:(��0�И<MS��ʓ�r�kڷ��lRu}q��?���V���g|�i��H��]2-X%U��R�\|9h�Xs��&g���܉9S8�\����bL�_`[.w}6��d�Ù
IroD�N�*��\�Q��3|���X�k7�mYs����.�m���Ã�#��~�ǀ�8{�L�s`�O���]�T��
��
            [p] => ���ɺ;�n%\,b4�]7��)��Z���е삽�66i8a�`��P#�?.�ޙ,���sq��L�HF����{8��C ���"�
>H,���A������������H�g��̓3G�mBrY`�S�
            [q] => ���.VӦ�(����hZ�jTY���3���B��ք9SuMw&.^�Ƹ�d�T!9i�u�K�#�*Fc�FY��*\�iO0b���Б]iei���  �OMDӒw,V�wӾK��r�%X��[��˓4=-�h�2
            [dmp1] => �ី���X��U�ܵ���}�-#́�|~�.�=�0���SjN@����V+A�<e!$3��~�"��g�������~s��   y
x5�i��(�Y�X�;X�Tn���<w�$#�#��P�3�d�Uk�
            [dmq1] => �$�!Q3��Zk�{ӗ�\����I2[*V5���&kے��yr�����b�[1gpc�y?�0Gf3��i���=א�!ܜ�7�a^܉I��a$����v�x����˲�[=��ʹW�'���%�"�B
            [iqmp] => &���jx�� ������&��'��Ya�B�����)��H-�<�uĮ1��H���Fwy����Xbt[;����I�2*�6���������i�ډ���3@�;�Lt.�׽��`h�qb�N�2�"����
        )

    [type] => 0
)

所以,在javascript中,当我使用:

So, in javascript, when I use:

var rsa = new RSAKey();
rsa.setPublic('<?php echo to_hex($details['rsa']['n']) ?>', '<?php echo to_hex($details['rsa']['e']) ?>');

我没有为公众指数输入任何内容,当我尝试在服务器上解密时,它没有任何回报。

I am inputting nothing for the public exponent, and when I try to decrypt it on the server, it returns nothing.

其中,因为这是我发现的唯一可能性,我认为这可能是错误的原因。

Which, because that's the only possibility I have found, I think it may be the reason for the error.

我正在解密:

function prKeyDecrypt($data,$prKey,$passKey){
    $data = pack('H*', $data);
    $pkres = openssl_pkey_get_private($prKey,$passKey);
    if (openssl_private_decrypt($data, $r, $pkres)) {
       return $r;
    } else {
        return "error";
    }
}
if(isset($_POST['data'])echo prKeyDecrypt($_POST['data'],$prKey,$passKey);

其中 $ prKey $ passKey 都是从以前的 genKeys()语句中获得的。

有不同的方法或者使用不同的方法来使用服务器上的php生成的公钥信息来加密客户端上的javascript中的数据?这很好,所以我想使用我所拥有的,但是如果还有另外一种方式,它将工作(如一个不同的JavaScript库),好的工作比不工作更好。)

Is there a different way to do this, or perhaps a different way to use the public key information generated in php on the server to encrypt data in javascript on the client? This is set up nicely, so I'd like to use what I have, but if there's another way that it'll work (such as a different javascript library), well, working is better than not working. :)

推荐答案

这是一个有趣的难题。这是一个圆形的方法来获得模数和公共指数。

This is an interesting puzzle. Here is a round-about way to get the modulus and public exponent out.

您可以找到一个用PHP编写的简单ASN.1解析器 here 。生成RSA密钥对后:

You can find a simple ASN.1 parser written in PHP here. After you produce the RSA key pair:

// Create the keypair
$res = openssl_pkey_new();
$details = openssl_pkey_get_details($res);

您可以将公钥从PEM转换为ASN.1解析器的DER格式,然后提取解析器:

You can convert the public key from PEM to DER format for the ASN.1 parser, and then feed it to the parser:

function pem2der($pem)
{
    $matches = array();
    preg_match('~^-----BEGIN ([A-Z ]+)-----\s*?([A-Za-z0-9+=/\r\n]+)\s*?-----END \1-----\s*$~D', $pem, $matches);
    return base64_decode(str_replace(array("\r", "\n"), array('', ''), $matches[2]));
}

$der = pem2der($details['key']);
$asn = ASN_BASE::parseASNstring($der);

然后,您可以达到公钥的ASN.1格式,并拉出模数和指数 - 我们直接知道哪里可以找到它们。

Then you can reach into the ASN.1 format of the public key, and pull out the modulus and exponent -- we know directly where to find them.

这个特定的ASN.1解析器收集了一个修改后的Base64格式的值,可以颠倒,然后转换值到十六进制转移到客户端:

This particular ASN.1 parser collects the values in a modified-Base64 format which can be reversed and then the value converted to hex for transfer to the client:

function asn_integer_to_hex($value)
{
    // The ASN.1 parser strtr'd these -- strtr them back
    $bin = base64_decode(strtr($value, '-_', '+/'));
    // Remove any leading 0x00 byte, too, and return hex
    return bin2hex(ord($bin[0]) == 0 ? substr($bin, 1) : $bin);
}

$arr = $asn[0]->data[1]->data[0]->data;
$n = asn_integer_to_hex($arr[0]->value);
$e = asn_integer_to_hex($arr[1]->value);

这些应与私钥中找到的详细信息相匹配:

These should match the details found in the private key:

echo "$details n: ".bin2hex($details['rsa']['n'])."\n";
echo "$details e: ".bin2hex($details['rsa']['e'])."\n";

echo "n: ".$n."\n";
echo "e: ".$e."\n";

也就是说,如果$ details ['rsa']有任何要显示的内容。我不能解释为什么你的案件为空,但是你应该可以通过解析ASN.1来将公式拉出公钥。

That is, if $details['rsa'] has anything to show. I can't explain why ['e'] is empty in your case, but you should be able to pull the exponent out of the public key by parsing the ASN.1.

这篇关于openssl_pkey_get_details($ res)不返回公共指数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆