openssl_verify():无法将提供的密钥参数强制转换为 public 密钥
openssl_verify(): supplied key param cannot be coerced into a public key
我已经使用以下方法将 test_priv.ppk
文件转换为 test_priv.pem
文件:
- 启动 PuTTYgen。对于 Actions,选择 Load,然后导航到您的
.ppk 文件。
- 选择 .ppk 文件,然后选择打开。
- 从菜单
在 PuTTY 密钥生成器的顶部,选择 Conversions、Export
OpenSSH 密钥。注意:如果您没有输入密码,您会收到一个
PuTTYgen 警告。选择是。
- 命名文件并添加 .pem
扩展。
- 选择保存。
$private_key = file_get_contents(storage_path('test/test_priv.pem'));
// $private_key in xdebugger
"""
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAz3SbOsx5EAUe/dbiSLoAhH6smgcPalGpcKIHNOoJ3h9JTP9a
59mwUZy86G5KQ6wQEhPQzKydlhlruAMTZIrjU1vvDtejWy7pMJObhxXBi2+kiO5U
9nWUw7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulepw7S9Xuh3bKnRyVX1MH/igIhLAV54
fEO/ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9Jd+5GpPM6EuNMGObHCselpLxodM6A
qhv/FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZoQV9S5LR/UeR40A7s/j5RmA6tp8En
Wz0oGbtFrXADAjYvRBH4LEyeXwk18YJI165ZcQIBJQKCAQBk7J6LTrdvk8njRfGL
Kg4W8YRmm6aibOqlf0HGtwu4KuVjun9AXBCWZ+0yzd7wfThAJVDSRiMmbTtSmbZo
Q5EveNUp0LBV33hc0i/8hx/i+Ara1M9jJHHiqmV86meeDFsDhJYvHL1jWjQ6aQwa
OHwaBOaBMtJQifdbBzkC1m4wsCDUl/waHzcwfhAO58UjxlktoSgJy+r+5NQVxvtm
yU4bfo/HIdjsseYKqELdghHvoi/Vn/rdZDXvLf5b1Nk6fniH0LpbOQFs1GaEbzdS
Y76rb0REJ/oKIBipC9+nx6l3X4w4GgFBuNQkfA6iux9NrCffiK35pdhbq88bHmzY
W/aVAoGBAPtGpDSW+gAZiGQBBoWW9aPdkWpffpzc1BX0MghjcBQeiaTN+fhLtqEZ
ikawRv0n7TJlPGyPwXniKg5D7UedXz3HcAOEIVHdh7MQt7ACb4seJEH7c1o0FPmT
MJxms3n/ObAKA9Fj4e0EzOnHDbBEPoFmfqMCsp3ZrXXV/sayPteHAoGBANNbEBME
7SNrszl+zA9wBD7wx2IWRwTuY1csPRub9r92Nc+hM66LTTWwkNp2vGcsrH5mrMlT
RWussYc40ZyRvS6b4i34+ji5rrCxcr9rFH/fSCEH0oazqfc2t6+FxcJcV7K4pFNi
CfjJ71pCjFmB3OogT7aob8PI7F2ANr7aeZVHAoGBALCSgTm2MyKqKH2f2xHEBo7T
DDzpKInnSOzVHD0+9M/eG4iQvX4LsMQ7dex73ttoKiNpu8Hoeh5L5jOJrafyC5My
MwljxGMKX1s8Lgz6yuwjBLi+iGjmU+2ls3TSi/Tc3G3dhiRvs4P1iRL6k/9SjMmh
+B+FWut2XjcgwN6mxGAZAoGAHI/D5uT9c31Bu6lZ2JKYyjw2no1jiwt1NUsq2jer
uQIi8otn2VEYRYaQHYWqwdWaxPkeRLg50EfE9pj5uzZJ/2EsZxPOyWUzSE9UshVj
opPLehXQV2RjE5HFy5x0q4/wLOiE6KxiNmB6SneyGe70Vv1yjk4c8PGjZpTJILW9
ZzMCgYEA8IfYvijvOgqwGV9ALwkmJy8RBI6g0VuTZlGxC/L/Le18RGsmEM1JARPc
b+EuxTrje4suLSzv6WvD7ivhjGvBJVLTDGsbly50g0DU6nloWUQfj3XXXCQXAmz6
taQ3bgJ+YV+NSQ0vUyOsN8RztbkOH3t3JrLYPTNEgYiY4+uccSk=
-----END RSA PRIVATE KEY-----
"""
并生成public键test_pub
来自Actions保存Public键按钮
$public_key = [file_get_contents][1](storage_path('test/test_pub'));
// $public_key in xdebugger
"""
-----BEGIN RSA PUBLIC KEY-----
MIIBCAKCAQEAz3SbOsx5EAUe/dbiSLoAhH6smgcPalGpcKIHNOoJ3h9JTP9a59mw
UZy86G5KQ6wQEhPQzKydlhlruAMTZIrjU1vvDtejWy7pMJObhxXBi2+kiO5U9nWU
w7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulepw7S9Xuh3bKnRyVX1MH/igIhLAV54fEO/
ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9Jd+5GpPM6EuNMGObHCselpLxodM6Aqhv/
FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZoQV9S5LR/UeR40A7s/j5RmA6tp8EnWz0o
GbtFrXADAjYvRBH4LEyeXwk18YJI165ZcQIBJQ==
-----END RSA PUBLIC KEY-----
"""
但是,在使用 PHP-JWT 对有效负载进行编码和解码时。
use \Firebase\JWT\JWT;
$jwt = JWT::encode($payload, $private_key , 'RS256');
$decoded = JWT::decode($jwt, $public_key , array('RS256')); // ErrorException: openssl_verify(): supplied key param cannot be coerced into a public key
什么可能导致此错误?
您正在使用编码“PKCS1”中的 RSA 私钥和 RSA Public 密钥,这在 PHP OpenSSL 中不可用:
-----BEGIN RSA PRIVATE KEY-----
-----BEGIN RSA PUBLIC KEY-----
查看有关 PHP 的 OpenSSL 手册页的信息:https://www.php.net/manual/en/function.openssl-pkey-get-public.php#101513
要在您的程序中使用这些密钥,您需要将它们转换为“PKCS8”编码Private/Public 以
开头的密钥
-----BEGIN PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
您可以使用在线服务进行转换(但仅限于 Public 密钥,绝不能用于 私钥 ).
如果您想在本地进行,我推荐使用 OpenSSL 命令行工具(是的,它适用于这些“传统”PKCS1 密钥...)。只需使用此命令行:
openssl pkcs8 -topk8 -nocrypt -in rsaprivatekeypkcs1.pem -out rsaprivatekeypkcs8.pem
openssl rsa -RSAPublicKey_in -in rsapublickeypkcs1.pem -pubout -out rsapublickeypkcs8.pem
并且您收到这些密钥(从您问题中的演示密钥转换而来):
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDPdJs6zHkQBR79
1uJIugCEfqyaBw9qUalwogc06gneH0lM/1rn2bBRnLzobkpDrBASE9DMrJ2WGWu4
AxNkiuNTW+8O16NbLukwk5uHFcGLb6SI7lT2dZTDs5e5qPFviyzckIoLgi/25BYG
SbVSV6nDtL1e6HdsqdHJVfUwf+KAiEsBXnh8Q7+hzPdlko3Qg2E6XPQYIa+B1Ogw
wQxSr0l37kak8zoS40wY5scKx6WkvGh0zoCqG/8W8wPkLU1gPNXsRls4nvETXMS1
8poIpmhBX1LktH9R5HjQDuz+PlGYDq2nwSdbPSgZu0WtcAMCNi9EEfgsTJ5fCTXx
gkjXrllxAgElAoIBAGTsnotOt2+TyeNF8YsqDhbxhGabpqJs6qV/Qca3C7gq5WO6
f0BcEJZn7TLN3vB9OEAlUNJGIyZtO1KZtmhDkS941SnQsFXfeFzSL/yHH+L4CtrU
z2MkceKqZXzqZ54MWwOEli8cvWNaNDppDBo4fBoE5oEy0lCJ91sHOQLWbjCwINSX
/BofNzB+EA7nxSPGWS2hKAnL6v7k1BXG+2bJTht+j8ch2Oyx5gqoQt2CEe+iL9Wf
+t1kNe8t/lvU2Tp+eIfQuls5AWzUZoRvN1JjvqtvREQn+gogGKkL36fHqXdfjDga
AUG41CR8DqK7H02sJ9+Irfml2FurzxsebNhb9pUCgYEA+0akNJb6ABmIZAEGhZb1
o92Ral9+nNzUFfQyCGNwFB6JpM35+Eu2oRmKRrBG/SftMmU8bI/BeeIqDkPtR51f
PcdwA4QhUd2HsxC3sAJvix4kQftzWjQU+ZMwnGazef85sAoD0WPh7QTM6ccNsEQ+
gWZ+owKyndmtddX+xrI+14cCgYEA01sQEwTtI2uzOX7MD3AEPvDHYhZHBO5jVyw9
G5v2v3Y1z6EzrotNNbCQ2na8ZyysfmasyVNFa6yxhzjRnJG9LpviLfj6OLmusLFy
v2sUf99IIQfShrOp9za3r4XFwlxXsrikU2IJ+MnvWkKMWYHc6iBPtqhvw8jsXYA2
vtp5lUcCgYEAsJKBObYzIqoofZ/bEcQGjtMMPOkoiedI7NUcPT70z94biJC9fguw
xDt17Hve22gqI2m7weh6HkvmM4mtp/ILkzIzCWPEYwpfWzwuDPrK7CMEuL6IaOZT
7aWzdNKL9Nzcbd2GJG+zg/WJEvqT/1KMyaH4H4Va63ZeNyDA3qbEYBkCgYAcj8Pm
5P1zfUG7qVnYkpjKPDaejWOLC3U1SyraN6u5AiLyi2fZURhFhpAdharB1ZrE+R5E
uDnQR8T2mPm7Nkn/YSxnE87JZTNIT1SyFWOik8t6FdBXZGMTkcXLnHSrj/As6ITo
rGI2YHpKd7IZ7vRW/XKOThzw8aNmlMkgtb1nMwKBgQDwh9i+KO86CrAZX0AvCSYn
LxEEjqDRW5NmUbEL8v8t7XxEayYQzUkBE9xv4S7FOuN7iy4tLO/pa8PuK+GMa8El
UtMMaxuXLnSDQNTqeWhZRB+PdddcJBcCbPq1pDduAn5hX41JDS9TI6w3xHO1uQ4f
e3cmstg9M0SBiJjj65xxKQ==
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAz3SbOsx5EAUe/dbiSLoA
hH6smgcPalGpcKIHNOoJ3h9JTP9a59mwUZy86G5KQ6wQEhPQzKydlhlruAMTZIrj
U1vvDtejWy7pMJObhxXBi2+kiO5U9nWUw7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulep
w7S9Xuh3bKnRyVX1MH/igIhLAV54fEO/ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9J
d+5GpPM6EuNMGObHCselpLxodM6Aqhv/FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZo
QV9S5LR/UeR40A7s/j5RmA6tp8EnWz0oGbtFrXADAjYvRBH4LEyeXwk18YJI165Z
cQIBJQ==
-----END PUBLIC KEY-----
使用这些密钥,验证(只需要 Public 密钥)应该可以工作。
我已经使用以下方法将 test_priv.ppk
文件转换为 test_priv.pem
文件:
- 启动 PuTTYgen。对于 Actions,选择 Load,然后导航到您的 .ppk 文件。
- 选择 .ppk 文件,然后选择打开。
- 从菜单 在 PuTTY 密钥生成器的顶部,选择 Conversions、Export OpenSSH 密钥。注意:如果您没有输入密码,您会收到一个 PuTTYgen 警告。选择是。
- 命名文件并添加 .pem 扩展。
- 选择保存。
$private_key = file_get_contents(storage_path('test/test_priv.pem'));
// $private_key in xdebugger
"""
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAz3SbOsx5EAUe/dbiSLoAhH6smgcPalGpcKIHNOoJ3h9JTP9a
59mwUZy86G5KQ6wQEhPQzKydlhlruAMTZIrjU1vvDtejWy7pMJObhxXBi2+kiO5U
9nWUw7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulepw7S9Xuh3bKnRyVX1MH/igIhLAV54
fEO/ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9Jd+5GpPM6EuNMGObHCselpLxodM6A
qhv/FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZoQV9S5LR/UeR40A7s/j5RmA6tp8En
Wz0oGbtFrXADAjYvRBH4LEyeXwk18YJI165ZcQIBJQKCAQBk7J6LTrdvk8njRfGL
Kg4W8YRmm6aibOqlf0HGtwu4KuVjun9AXBCWZ+0yzd7wfThAJVDSRiMmbTtSmbZo
Q5EveNUp0LBV33hc0i/8hx/i+Ara1M9jJHHiqmV86meeDFsDhJYvHL1jWjQ6aQwa
OHwaBOaBMtJQifdbBzkC1m4wsCDUl/waHzcwfhAO58UjxlktoSgJy+r+5NQVxvtm
yU4bfo/HIdjsseYKqELdghHvoi/Vn/rdZDXvLf5b1Nk6fniH0LpbOQFs1GaEbzdS
Y76rb0REJ/oKIBipC9+nx6l3X4w4GgFBuNQkfA6iux9NrCffiK35pdhbq88bHmzY
W/aVAoGBAPtGpDSW+gAZiGQBBoWW9aPdkWpffpzc1BX0MghjcBQeiaTN+fhLtqEZ
ikawRv0n7TJlPGyPwXniKg5D7UedXz3HcAOEIVHdh7MQt7ACb4seJEH7c1o0FPmT
MJxms3n/ObAKA9Fj4e0EzOnHDbBEPoFmfqMCsp3ZrXXV/sayPteHAoGBANNbEBME
7SNrszl+zA9wBD7wx2IWRwTuY1csPRub9r92Nc+hM66LTTWwkNp2vGcsrH5mrMlT
RWussYc40ZyRvS6b4i34+ji5rrCxcr9rFH/fSCEH0oazqfc2t6+FxcJcV7K4pFNi
CfjJ71pCjFmB3OogT7aob8PI7F2ANr7aeZVHAoGBALCSgTm2MyKqKH2f2xHEBo7T
DDzpKInnSOzVHD0+9M/eG4iQvX4LsMQ7dex73ttoKiNpu8Hoeh5L5jOJrafyC5My
MwljxGMKX1s8Lgz6yuwjBLi+iGjmU+2ls3TSi/Tc3G3dhiRvs4P1iRL6k/9SjMmh
+B+FWut2XjcgwN6mxGAZAoGAHI/D5uT9c31Bu6lZ2JKYyjw2no1jiwt1NUsq2jer
uQIi8otn2VEYRYaQHYWqwdWaxPkeRLg50EfE9pj5uzZJ/2EsZxPOyWUzSE9UshVj
opPLehXQV2RjE5HFy5x0q4/wLOiE6KxiNmB6SneyGe70Vv1yjk4c8PGjZpTJILW9
ZzMCgYEA8IfYvijvOgqwGV9ALwkmJy8RBI6g0VuTZlGxC/L/Le18RGsmEM1JARPc
b+EuxTrje4suLSzv6WvD7ivhjGvBJVLTDGsbly50g0DU6nloWUQfj3XXXCQXAmz6
taQ3bgJ+YV+NSQ0vUyOsN8RztbkOH3t3JrLYPTNEgYiY4+uccSk=
-----END RSA PRIVATE KEY-----
"""
并生成public键test_pub
来自Actions保存Public键按钮
$public_key = [file_get_contents][1](storage_path('test/test_pub'));
// $public_key in xdebugger
"""
-----BEGIN RSA PUBLIC KEY-----
MIIBCAKCAQEAz3SbOsx5EAUe/dbiSLoAhH6smgcPalGpcKIHNOoJ3h9JTP9a59mw
UZy86G5KQ6wQEhPQzKydlhlruAMTZIrjU1vvDtejWy7pMJObhxXBi2+kiO5U9nWU
w7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulepw7S9Xuh3bKnRyVX1MH/igIhLAV54fEO/
ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9Jd+5GpPM6EuNMGObHCselpLxodM6Aqhv/
FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZoQV9S5LR/UeR40A7s/j5RmA6tp8EnWz0o
GbtFrXADAjYvRBH4LEyeXwk18YJI165ZcQIBJQ==
-----END RSA PUBLIC KEY-----
"""
但是,在使用 PHP-JWT 对有效负载进行编码和解码时。
use \Firebase\JWT\JWT;
$jwt = JWT::encode($payload, $private_key , 'RS256');
$decoded = JWT::decode($jwt, $public_key , array('RS256')); // ErrorException: openssl_verify(): supplied key param cannot be coerced into a public key
什么可能导致此错误?
您正在使用编码“PKCS1”中的 RSA 私钥和 RSA Public 密钥,这在 PHP OpenSSL 中不可用:
-----BEGIN RSA PRIVATE KEY-----
-----BEGIN RSA PUBLIC KEY-----
查看有关 PHP 的 OpenSSL 手册页的信息:https://www.php.net/manual/en/function.openssl-pkey-get-public.php#101513
要在您的程序中使用这些密钥,您需要将它们转换为“PKCS8”编码Private/Public 以
开头的密钥-----BEGIN PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
您可以使用在线服务进行转换(但仅限于 Public 密钥,绝不能用于 私钥 ).
如果您想在本地进行,我推荐使用 OpenSSL 命令行工具(是的,它适用于这些“传统”PKCS1 密钥...)。只需使用此命令行:
openssl pkcs8 -topk8 -nocrypt -in rsaprivatekeypkcs1.pem -out rsaprivatekeypkcs8.pem
openssl rsa -RSAPublicKey_in -in rsapublickeypkcs1.pem -pubout -out rsapublickeypkcs8.pem
并且您收到这些密钥(从您问题中的演示密钥转换而来):
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDPdJs6zHkQBR79
1uJIugCEfqyaBw9qUalwogc06gneH0lM/1rn2bBRnLzobkpDrBASE9DMrJ2WGWu4
AxNkiuNTW+8O16NbLukwk5uHFcGLb6SI7lT2dZTDs5e5qPFviyzckIoLgi/25BYG
SbVSV6nDtL1e6HdsqdHJVfUwf+KAiEsBXnh8Q7+hzPdlko3Qg2E6XPQYIa+B1Ogw
wQxSr0l37kak8zoS40wY5scKx6WkvGh0zoCqG/8W8wPkLU1gPNXsRls4nvETXMS1
8poIpmhBX1LktH9R5HjQDuz+PlGYDq2nwSdbPSgZu0WtcAMCNi9EEfgsTJ5fCTXx
gkjXrllxAgElAoIBAGTsnotOt2+TyeNF8YsqDhbxhGabpqJs6qV/Qca3C7gq5WO6
f0BcEJZn7TLN3vB9OEAlUNJGIyZtO1KZtmhDkS941SnQsFXfeFzSL/yHH+L4CtrU
z2MkceKqZXzqZ54MWwOEli8cvWNaNDppDBo4fBoE5oEy0lCJ91sHOQLWbjCwINSX
/BofNzB+EA7nxSPGWS2hKAnL6v7k1BXG+2bJTht+j8ch2Oyx5gqoQt2CEe+iL9Wf
+t1kNe8t/lvU2Tp+eIfQuls5AWzUZoRvN1JjvqtvREQn+gogGKkL36fHqXdfjDga
AUG41CR8DqK7H02sJ9+Irfml2FurzxsebNhb9pUCgYEA+0akNJb6ABmIZAEGhZb1
o92Ral9+nNzUFfQyCGNwFB6JpM35+Eu2oRmKRrBG/SftMmU8bI/BeeIqDkPtR51f
PcdwA4QhUd2HsxC3sAJvix4kQftzWjQU+ZMwnGazef85sAoD0WPh7QTM6ccNsEQ+
gWZ+owKyndmtddX+xrI+14cCgYEA01sQEwTtI2uzOX7MD3AEPvDHYhZHBO5jVyw9
G5v2v3Y1z6EzrotNNbCQ2na8ZyysfmasyVNFa6yxhzjRnJG9LpviLfj6OLmusLFy
v2sUf99IIQfShrOp9za3r4XFwlxXsrikU2IJ+MnvWkKMWYHc6iBPtqhvw8jsXYA2
vtp5lUcCgYEAsJKBObYzIqoofZ/bEcQGjtMMPOkoiedI7NUcPT70z94biJC9fguw
xDt17Hve22gqI2m7weh6HkvmM4mtp/ILkzIzCWPEYwpfWzwuDPrK7CMEuL6IaOZT
7aWzdNKL9Nzcbd2GJG+zg/WJEvqT/1KMyaH4H4Va63ZeNyDA3qbEYBkCgYAcj8Pm
5P1zfUG7qVnYkpjKPDaejWOLC3U1SyraN6u5AiLyi2fZURhFhpAdharB1ZrE+R5E
uDnQR8T2mPm7Nkn/YSxnE87JZTNIT1SyFWOik8t6FdBXZGMTkcXLnHSrj/As6ITo
rGI2YHpKd7IZ7vRW/XKOThzw8aNmlMkgtb1nMwKBgQDwh9i+KO86CrAZX0AvCSYn
LxEEjqDRW5NmUbEL8v8t7XxEayYQzUkBE9xv4S7FOuN7iy4tLO/pa8PuK+GMa8El
UtMMaxuXLnSDQNTqeWhZRB+PdddcJBcCbPq1pDduAn5hX41JDS9TI6w3xHO1uQ4f
e3cmstg9M0SBiJjj65xxKQ==
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAz3SbOsx5EAUe/dbiSLoA
hH6smgcPalGpcKIHNOoJ3h9JTP9a59mwUZy86G5KQ6wQEhPQzKydlhlruAMTZIrj
U1vvDtejWy7pMJObhxXBi2+kiO5U9nWUw7OXuajxb4ss3JCKC4Iv9uQWBkm1Ulep
w7S9Xuh3bKnRyVX1MH/igIhLAV54fEO/ocz3ZZKN0INhOlz0GCGvgdToMMEMUq9J
d+5GpPM6EuNMGObHCselpLxodM6Aqhv/FvMD5C1NYDzV7EZbOJ7xE1zEtfKaCKZo
QV9S5LR/UeR40A7s/j5RmA6tp8EnWz0oGbtFrXADAjYvRBH4LEyeXwk18YJI165Z
cQIBJQ==
-----END PUBLIC KEY-----
使用这些密钥,验证(只需要 Public 密钥)应该可以工作。