openssl_pkey_get_details($res) 不返回公共指数

2024-06-19

我在用着这个例子 https://stackoverflow.com/a/12575951/2016196使用 php 生成的密钥进行 javascript 加密openssl图书馆,但是$details = openssl_pkey_get_details($resource)没有返回公共指数($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数组,我得到:

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 中,当我使用:

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

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

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

我正在解密它:

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);

Where $prKey and $passKey都是从之前得到的genKeys()陈述。

是否有不同的方法来做到这一点,或者可能是使用服务器上的 php 中生成的公钥信息来加密客户端上的 javascript 中的数据的不同方法?设置得很好,所以我想使用我所拥有的,但如果有其他方法可以工作(例如不同的 javascript 库),那么,工作总比不工作好。 :)


这是一个有趣的谜题。这是一种获取模数和公共指数的迂回方法。

您可以找到一个用 PHP 编写的简单 ASN.1 解析器here http://www.phpkode.com/source/s/mistpark-server/library/asn1.php。生成 RSA 密钥对后:

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

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

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 格式的公钥,并提取模数和指数 - 我们直接知道在哪里可以找到它们。

这个特定的 ASN.1 解析器收集修改后的 Base64 格式的值,该格式可以反转,然后将值转换为十六进制以传输到客户端:

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);

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

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'] 有任何内容要显示。我无法解释为什么 ['e'] 在您的情况下为空,但您应该能够通过解析 ASN.1 从公钥中提取指数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openssl_pkey_get_details($res) 不返回公共指数 的相关文章

随机推荐