Is there a possibility in PHP's OpenSSL implementation to encrypt via public key/decrypt via private key using PHP OpenSSL?
As per the OpenSSL documentation, openssl_seal() does not support an EC public key.
The public key must be RSA because it is the only OpenSSL public key
algorithm that supports key transport.
openssl_public_encrypt() also throws an error when using it with an EC key.
My key creation works as follows:
// Configuration settings for the key
$config = array(
"private_key_type" => OPENSSL_KEYTYPE_EC,
"curve_name" => "secp521r1"
);
// Create the private and public key
$res = openssl_pkey_new($config);
// Extract the private key into $private_key
openssl_pkey_export($res, $private_key);
// Extract the public key into $public_key
$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];
Is there any way to do ec public key encryption with OpenSSL?
Why is the failure of openssl() and openssl_public_encrypt() for EC not documented at php.net?
Related
I'm trying to convert key pair from PEM format :
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
Into XML format :
<RSAKeyValue>
<Exponent> </Exponent>
<Modulus> </Modulus>
</RSAKeyValue>
Is it possible using only openssl as I generate the keys through it ?
nb : my keys are stored into $privKey and $pubKey variable for test purpose, so I want to be able to $echo the XML format key and not store it into a file for the moment.
nb' : I have tried using phpseclib with an exemple found here but it gives me this error "Uncaught Error: Class "BaseController" not found in ..."
Thanks for your help
Here is the PHP code :
<?php
$config = array
(
'config' => 'C:\xampp\htdocs\crypto\openssl.cnf',
'default_md' => 'sha512',
'private_key_bits' => 4096,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
);
$keypair = openssl_pkey_new($config);
openssl_pkey_export($keypair, $privKey, null, $config);
$publickey = openssl_pkey_get_details($keypair);
$pubKey = $publickey['key'];
use phpseclib3\Crypt\RSA;
echo $pubKey->toString("XML");
echo "$privKey";
?>
The conversion of a PEM encoded key in X.509/SPKI format to XML format can be done with phpseclib as follows:
use phpseclib3\Crypt\PublicKeyLoader;
$x509pem = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunF5aDa6HCfLMMI/MZLT
5hDk304CU+ypFMFiBjowQdUMQKYHZ+fklB7GpLxCatxYJ/hZ7rjfHH3Klq20/Y1E
bYDRopyTSfkrTzPzwsX4Ur/l25CtdQldhHCTMgwf/Ev/buBNobfzdZE+Dhdv5lQw
KtjI43lDKvAi5kEet2TFwfJcJrBiRJeEcLfVgWTXGRQn7gngWKykUu5rS83eAU1x
H9FLojQfyia89/EykiOO7/3UWwd+MATZ9HLjSx2/Lf3g2jr81eifEmYDlri/OZp4
OhZu+0Bo1LXloCTe+vmIQ2YCX7EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4i
GwIDAQAB
-----END PUBLIC KEY-----';
$publicKey = PublicKeyLoader::load($x509pem); // import public PEM key
$xmlFormattedKey = $publicKey->toString("XML"); // export public XML key
print($xmlFormattedKey);
The output is:
<RSAKeyValue>
<Modulus>unF5aDa6HCfLMMI/MZLT5hDk304CU+ypFMFiBjowQdUMQKYHZ+fklB7GpLxCatxYJ/hZ7rjfHH3Klq20/Y1EbYDRopyTSfkrTzPzwsX4Ur/l25CtdQldhHCTMgwf/Ev/buBNobfzdZE+Dhdv5lQwKtjI43lDKvAi5kEet2TFwfJcJrBiRJeEcLfVgWTXGRQn7gngWKykUu5rS83eAU1xH9FLojQfyia89/EykiOO7/3UWwd+MATZ9HLjSx2/Lf3g2jr81eifEmYDlri/OZp4OhZu+0Bo1LXloCTe+vmIQ2YCX7EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4iGw==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
For key generation OpenSSL can be used as in your code. However, the exported PEM key must be imported in the phpseclib part as shown in the code above (this import is missing in your code):
// Key generation with OpenSSL
$config = array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config); // create key resource using $config
//openssl_pkey_export($res, $privKey); // export private key (PEM encoded, PKCS#8 format); not required for this example
$pubKeyDetails = openssl_pkey_get_details($res);
$x509pem = $pubKeyDetails["key"]; // export public key (PEM encoded, X.509 format)
// Key conversion with phpseclib
$publicKey = PublicKeyLoader::load($x509pem); // import public PEM key generated with OpenSSL
$xmlFormattedKey = $publicKey->toString("XML"); // export public XML key
print($xmlFormattedKey);
Alternatively, also key generation can be done with phpseclib:
use phpseclib3\Crypt\RSA;
$privateKey = RSA::createKey(2048); // generate private key
$xmlFormattedKey = $privateKey->getPublicKey()->toString("XML"); // export public XML key
print($xmlFormattedKey);
I want to encode and decode my data using Laravel PHP-JWT package. which require Private and Public Key in string format.
Therefore, I have created the certificate.pem by converting .crt to .pem format using below command
x509 -inform DER -outform PEM -in cert.crt -out certificate.pem
As openssl_pkey_get_private and openssl_pkey_get_public accept certificate in .pem format as parameter and Return Positive Key Resources.
Note: Positive Key Resouces is resource id='588' type='OpenSSL key' in debugging.
/* Path to certificate */
$path = storage_path('test/certificate.pem');
/* Extract the private key from $res to $privKey */
$privKey = openssl_pkey_get_private($path);
/* Extract the public key from $res to $pubKey */
$pubKey = openssl_pkey_get_public($path);
Query 1: Returning false in both $privKey and $pubKey
Query 2: Will JWT::encode accept as a parameter these Key Resouces object which is returning from OpenSSL function?
Is there any alternative?
Edit 1: I have OpenSSL enabled in phpinfo.
Edit 2: openssl_error_string output.
$path = storage_path('test/certificate.pem');
$private_key = openssl_pkey_get_private(file_get_contents($path)); // resource id='565' type='OpenSSL key'
$public_key = openssl_pkey_get_public(file_get_contents($path)); // false
$pubkey_error_message = openssl_error_string(); // "error:0909006C:PEM routines:get_name:no start line"
I am trying to create a JWT token. The other server is storing the public key in a single line and using that for validation.
Also, the public key being used for validation is in single line.
So, to generate the correct JWT token, what I think is I should also use the private key in a single line (may be with \n or may be without).
I am using openssl_sign to generate the token, which uses openssl_reource as key. I get that paramter from openssl_pkey_get_private.
But problem which happens in this case is, it either accepts the pem file path, or the key in PEM string format. So, if I pass the private_key as a single line, it doesn't give me the required output.
So, how can I resolve this. As I see other language libraries able to generate signature by passing private key in a single line.
In PHP the key can be formatted with line breaks or as a one-liner (with \n). Both works. In the following example I use a 512-bit encrypted RSA-key for simplicity (although in practice a larger key (>= 2048 bit) must be used for security reasons):
<?php
// Private key: 512 bit for simplicity
// Passphrase: MyPassphrase
// openssl genrsa -aes256 -out private.pem 512
$privKeyEnc = "-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,8F2D6F9594B3D379BF9D9748BD174458
RP2fyz1VNBKHiCadC5B9fjxV7z7AMAqbsN2vykFfPhdUFsxlJaecEeTMT7s6IbZN
Pr80+ljLjJ0SxJiK+j8DAc/Wrf+qyYUFcWbsvOhUIPyB5ww9+mEeIERJCigsyZJ7
k/Apau/BypdC9vCXKB3wM9FcmvP1g/ZwVoXfN3TIPEfWTktvuf74yFNoIaVbZAK/
+tzAGduu9wLkr6WTq4Isqy/IPjVCp9VwH1wNnz+hjkO7oELcCpFieIvAidUMKBR9
EdexLQCimbOl2wlfRNLincK8+FDOVWx6ElFFQlhzyWQCt8ed1fdiAggKxOco4Ww2
tFjIzaO4KXlbc9JFGd9PzigpftN/aHbk3c+x0E+3q5u8eySai4vgk38s1KaE7rn/
rarCgtGxOlbbTkI3opkjIrGlrsEyexKtS23mI/Dgcco=
-----END RSA PRIVATE KEY-----";
// One-liner using \n
$privKeyEnc_1Line = "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,8F2D6F9594B3D379BF9D9748BD174458\n\nRP2fyz1VNBKHiCadC5B9fjxV7z7AMAqbsN2vykFfPhdUFsxlJaecEeTMT7s6IbZN\nPr80+ljLjJ0SxJiK+j8DAc/Wrf+qyYUFcWbsvOhUIPyB5ww9+mEeIERJCigsyZJ7\nk/Apau/BypdC9vCXKB3wM9FcmvP1g/ZwVoXfN3TIPEfWTktvuf74yFNoIaVbZAK/\n+tzAGduu9wLkr6WTq4Isqy/IPjVCp9VwH1wNnz+hjkO7oELcCpFieIvAidUMKBR9\nEdexLQCimbOl2wlfRNLincK8+FDOVWx6ElFFQlhzyWQCt8ed1fdiAggKxOco4Ww2\ntFjIzaO4KXlbc9JFGd9PzigpftN/aHbk3c+x0E+3q5u8eySai4vgk38s1KaE7rn/\nrarCgtGxOlbbTkI3opkjIrGlrsEyexKtS23mI/Dgcco=\n-----END RSA PRIVATE KEY-----";
// Public key:
// Passphrase: MyPassphrase
// openssl rsa -in private.pem -outform PEM -pubout -out public.pem
$pubKey = "-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMjYQLbdIVgKX1mSyKijOIpmlB9YWui1
KoCniRNHUPEsxth+o9fZXZMo1gzh9ZlFs6VLiyU7kv2+5QElOnhNzwcCAwEAAQ==
-----END PUBLIC KEY-----";
// One-liner using \n
$pubKey_1Line = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMjYQLbdIVgKX1mSyKijOIpmlB9YWui1\nKoCniRNHUPEsxth+o9fZXZMo1gzh9ZlFs6VLiyU7kv2+5QElOnhNzwcCAwEAAQ==\n-----END PUBLIC KEY-----";
$dataToSign = 'The quick brown fox jumps over the lazy dog.';
// Signing
//$privateKey = openssl_pkey_get_private("$privKeyEnc", "MyPassphrase"); // also works
$privateKey = openssl_pkey_get_private("$privKeyEnc_1Line", "MyPassphrase");
openssl_sign($dataToSign, $signature, $privateKey, 'sha256');
$signatureBase64 = base64_encode($signature);
print("Signature (Base64): ".$signatureBase64."<br>");
// Verifying
$publicKey = openssl_pkey_get_public("$pubKey");
//$publicKey = openssl_pkey_get_public("$pubKey_1Line"); // also works
$verified = openssl_verify($dataToSign, $signature, $publicKey,'sha256');
print("Verification: ".$verified."<br>");
/*
Output:
Signature (Base64): KVuUd+xy6at0emmhF20rbiD9lWzIN9euwKbeEm7aMvxqEkJ68HrjAoDJ37R3QGPI24woXY3TON9pahAhx+YNhQ==
Verification: 1
*/
?>
I'm basically trying to create a signature using "openssl" (PHP) and verify that using "criptografy" (PYTHON). And I'm always getting the error "InvalidSignature", which means I'm doing something wrong. I know that they are different languages and libraries but once I'm using the same algorithm for both I expected to get a valid signature. I appreciate any help.
PHP: creating public key and signature without problems
$config = array(
"digest_alg" => "sha256",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $privKey);
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
error_log($pubKey);
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtXyDj9vqTGkR/ITYZ6+e
xXATzalUOdBcqee+qcb5NJ6Z5DgNdYi9lWz/4YfitYKp0EFwPzbem1zBzKbuQSko
y7zRjpmyGbw8Q6wexO4SyA44jxs75JNXMA2x22dkNKajRE5kXngBIF1ixpzCxvvc
kfyewM8C8y2iAy5j02YZYw9ysrQWJegamq6sidnMCJBtokOnPQaNJwbDQTqwrSRS
8IDy7BtBHB7F/bBwLArwxG7aLFjJ9vf2F7HpmZ3VvJa69OhY0pZMSqePQpJBIQ+2
ztIywpKkOukJz22Brqoe0ygMQzVrcYoj2MZ8CSiKUCJL6Wm9ErFXvBh/XqPWjX1t
nWdnF6qSD/2itIw18+PzCWYaoeu6w064dcbRrUQ4UOYxp69IFtrv5OHAsuWPJ27q
2IUCZ9DWWphlwhz+lI4rAb6whd2R8Sb7vEhvSz4Kd5kIjel9Dt8mJ+jGyhTjqIhP
7amgcOQLKZJfmeltYI+F0U8oJcOPhxtlxfFB1MIxPDHvCcdR93LJGgU6NboTwcpx
hnoI86xKblJmnxMxuQbUfPRU8vAuiizKVrpQS8z2k58mlxa9+hykjMcqpAvQ6STM
vLswdj0j9aqyv6I94z2Q2Lgcuoh7xSJcLhKN9QGaarUqjAY/zoZPiDnCxXlnVrav
BMyQZ9PqbsaHsd7pVVpuW8MCAwEAAQ==
-----END PUBLIC KEY-----
$data = 'oi';
$pkeyid = openssl_pkey_get_private($privKey);
openssl_sign($data, $signature, $pkeyid);
error_log(base64_encode($signature));
MoUZzfaHCwME2mmxJnMBQWgo+lTLK2QfpfD+5IEnSwi0wmRtgZgFl7IGsWYlTO+zTQCcB/aKg91CMClmb5P2jEtOkY3ie2pNflEIsc3aGqfWoVpHJUMoft+4hytzgMszqwgbJdo6eac7zIxlrzmeb4jb58APtc4aaLLQru2Gga9oPRyCqbXrD0TXnQ6GzjDNGwi6wP30NU9KaHWaGfeq1WSqsAIaIbi2oG4MeWJYX6SOB/CX1Jg8SJYzWQahpJeybE4Z8fR6ncuvfbjp9aet1aKsPB/DFPQ5VFaAS4oItVb0Ha4wkQ8YgJu5fEUK7X9KzuOwidja5RLZtwDPa0bBSveCw9D8FUsguilaoIu7ueDPTRueK4bQkYstOc2OvVlzInukyOzFXVgZsiV23FTHrQ5FqHd9nCUbfuhgrMqHRYQmRFUgDaeyY+B5ve3bQ4lT3qm282ngKi8AZ+clB0VeaFiQxpF8SCCRMu0bX3dsQMaXRUeSVDipf3ZMABl9xXbzEjqXoJzuvC6tCnEv8K3HzKbjz2S1876eGy7opIixaUMwDu9QOiPoSiFUY/xCsX8D1Im8Mv4eyzWNV3FL1U/GS3LZzkq/NuJdB7wjCib3ieHaYX/bvTpmAp/oO0+vbI2pzq9w71cpqQpsNsOZSGkgY2q1sO6u0I5jCFScdJVbJl0=
PYTHON: InvalidSignature error
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.serialization import load_pem_public_key
signature= 'MoUZzfaHCwME2mmxJnMBQWgo+lTLK2QfpfD+5IEnSwi0wmRtgZgFl7IGsWYlTO+zTQCcB/aKg91CMClmb5P2jEtOkY3ie2pNflEIsc3aGqfWoVpHJUMoft+4hytzgMszqwgbJdo6eac7zIxlrzmeb4jb58APtc4aaLLQru2Gga9oPRyCqbXrD0TXnQ6GzjDNGwi6wP30NU9KaHWaGfeq1WSqsAIaIbi2oG4MeWJYX6SOB/CX1Jg8SJYzWQahpJeybE4Z8fR6ncuvfbjp9aet1aKsPB/DFPQ5VFaAS4oItVb0Ha4wkQ8YgJu5fEUK7X9KzuOwidja5RLZtwDPa0bBSveCw9D8FUsguilaoIu7ueDPTRueK4bQkYstOc2OvVlzInukyOzFXVgZsiV23FTHrQ5FqHd9nCUbfuhgrMqHRYQmRFUgDaeyY+B5ve3bQ4lT3qm282ngKi8AZ+clB0VeaFiQxpF8SCCRMu0bX3dsQMaXRUeSVDipf3ZMABl9xXbzEjqXoJzuvC6tCnEv8K3HzKbjz2S1876eGy7opIixaUMwDu9QOiPoSiFUY/xCsX8D1Im8Mv4eyzWNV3FL1U/GS3LZzkq/NuJdB7wjCib3ieHaYX/bvTpmAp/oO0+vbI2pzq9w71cpqQpsNsOZSGkgY2q1sO6u0I5jCFScdJVbJl0='
decoded = base64.b64decode(signature)
plaintextMessage="oi"
# /tmp/public contains the public key
alicePubKey = load_pem_public_key(open('/tmp/public', 'rb').read(),default_backend())
ciphertext = alicePubKey.verify(
decoded,
plaintextMessage,
padding.PSS(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH,
),
hashes.SHA256()
)
It's pretty clear that your PHP code:
Signed using RSA with SHA1, not SHA256
Used PKCS#1 version 1.5 padding, not PSS
It looks like you just copy&pasted your code from the cryptography package documentation.
Thus the following python snippet should verify:
ciphertext = alicePubKey.verify(
decoded,
b'oi',
padding.PKCS1v15(),
hashes.SHA1()
)
PSS and SHA-256 are better choices, so you should investigate modifying your PHP code to use those instead of modifying your python code.
As James said, the function openssl_sign was using SHA1 by default, what could be solved with the parameter OPENSSL_ALGO_SHA256.
So I did these changes:
PHP
openssl_sign($data, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
Python
ciphertext = alicePubKey.verify(
decoded,
plaintextMessage,
padding.PKCS1v15(),
hashes.SHA256()
)
To authenticate a google oauth2 token, I'm generating a public key for kid "b863b534069bfc0207197bcf831320d1cdc2cee2" from the modulus (n) and exponent (e) from:
https://www.googleapis.com/oauth2/v3/certs
{
"alg": "RS256",
"n": "8h6tCwOYDPtzyFivNaIguQVc_yBO5eOA2kUu_MAN8s4VWn8tIfCbVvcAz3yNwQuGpkdNg8gTk9QmReXl4SE8m7aCa0iRcBBWLyPUt6TM1RkYE51rOGYhjWxo9V8ogMXSBclE6x0t8qFY00l5O34gjYzXtyvyBX7Sw5mGuNLVAzq2nsCTnIsHrIaBy70IKU3FLsJ_PRYyViXP1nfo9872q3mtn7bJ7_hqss0vDgUiNAqPztVIsrZinFbaTgXjLhBlUjFWgJx_g4p76CJkjQ3-puZRU5A0D04KvqQ_0AWcN1Q8pvwQ9V4uGHm6Bop9nUhIcZJYjjlTM9Pkx_JnVOfekw",
"use": "sig",
"kid": "b863b534069bfc0207197bcf831320d1cdc2cee2",
"e": "AQAB",
"kty": "RSA"
}
I then create the RSA 256 public key in php with:
$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64url_decode($cert["n"]), 256);
$exponent = new Math_BigInteger(base64url_decode($cert["e"]), 256);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$public_key = $rsa->getPublicKey();
This generates public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuopEuQyOKMsQq90I/5on
1nNBPc7stMvsN1HC+Pgyu8nJ1qWwaAAqIv4edo2oG/Bo3eg6p+OjG3nbFL62S6hE
aJLUVfxhW5GQuxQlsvaA2MsZuZCRyKTv8bm641wM+biGVZLiDsLRylVdpxf4aGa9
9zZw+QZMVKL4f9B4SunyTugTaCIu8LBOQesCQp/QJaUjqMDhfEvoFQXiCn6zo3rW
EWBiKxiFBizH9jSfWimJecFhn0Vlv/Vs7pRb0X2y66VS3gTvR6/A3ooNz3tYAJPM
GoE8fAiEghYXXHjmWmgdRx9Qt9sa/ACwv7yx0Th27fw+rrsMSrUyaqRpn/fjIMTu
sQIDAQAB
-----END PUBLIC KEY-----
This same method worked with dozens of other RS256 kid's from google, but the public key does not work with this particular kid.
I am verifying the signature with:
openssl_verify($payload_to_verify, $safe_signature, $public_key, OPENSSL_ALGO_SHA256);
Which responds with '0' for failure.
Edit #2: Found google's version of the public key at:
https://www.googleapis.com/oauth2/v1/certs
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8h6tCwOYDPtzyFivNaIg
uQVc/yBO5eOA2kUu/MAN8s4VWn8tIfCbVvcAz3yNwQuGpkdNg8gTk9QmReXl4SE8
m7aCa0iRcBBWLyPUt6TM1RkYE51rOGYhjWxo9V8ogMXSBclE6x0t8qFY00l5O34g
jYzXtyvyBX7Sw5mGuNLVAzq2nsCTnIsHrIaBy70IKU3FLsJ/PRYyViXP1nfo9872
q3mtn7bJ7/hqss0vDgUiNAqPztVIsrZinFbaTgXjLhBlUjFWgJx/g4p76CJkjQ3+
puZRU5A0D04KvqQ/0AWcN1Q8pvwQ9V4uGHm6Bop9nUhIcZJYjjlTM9Pkx/JnVOfe
kwIDAQAB
-----END PUBLIC KEY-----
My generated public key is different. Why my generated public key is wrong?
I confirm that the key is not correctly converted by the RSA Crypt package.
Wrong key
Good key
I tried to convert that key with another application (web-token/jwt-app) and I got the same result as the one provided by Google.
curl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar
curl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar.pubkey
chmod +x jose.phar
./jose.phar key:convert:pkcs1 '{"alg": "RS256","n": "8h6tCwOYDPtzyFivNaIguQVc_yBO5eOA2kUu_MAN8s4VWn8tIfCbVvcAz3yNwQuGpkdNg8gTk9QmReXl4SE8m7aCa0iRcBBWLyPUt6TM1RkYE51rOGYhjWxo9V8ogMXSBclE6x0t8qFY00l5O34gjYzXtyvyBX7Sw5mGuNLVAzq2nsCTnIsHrIaBy70IKU3FLsJ_PRYyViXP1nfo9872q3mtn7bJ7_hqss0vDgUiNAqPztVIsrZinFbaTgXjLhBlUjFWgJx_g4p76CJkjQ3-puZRU5A0D04KvqQ_0AWcN1Q8pvwQ9V4uGHm6Bop9nUhIcZJYjjlTM9Pkx_JnVOfekw","use": "sig","kid": "b863b534069bfc0207197bcf831320d1cdc2cee2","e": "AQAB","kty": "RSA"}'
Best would be to warn phpseclib/phpseclib about that issue.