Firebase PHP JWT“OpenSSL 无法验证数据:错误:0906D06C:PEM 例程:PEM_read_bio:no start line”

Posted

技术标签:

【中文标题】Firebase PHP JWT“OpenSSL 无法验证数据:错误:0906D06C:PEM 例程:PEM_read_bio:no start line”【英文标题】:Firebase PHP JWT "OpenSSL unable to verify data: error:0906D06C:PEM routines:PEM_read_bio:no start line" 【发布时间】:2017-02-18 01:36:16 【问题描述】:

我正在通过 App Engine 使用 Google Cloud php API。从客户端设备通过 POST 发送带有 Firebase 身份验证令牌的请求。根据 Firebase PHP JWT 的文档,我正在尝试使用以下代码解码令牌:

$decoded = JWT::decode($token, $key, array('RS256'));

$token 是这样的一行(出于安全原因,这是无效的):

eyJhbGciOiJSUzI1asdaNiIsImtpZCI6Ijk2N2Q3NzQ4YmM5NTMTIzNzRhZWQasdasd3MzEyYzcwNjEyZTRlNTM4NmUifQ.tuaAsjdlkjvsdngeoijAnlnbfgLkoosdfKLnm,werkldsfNkndfkdsnfkfnlNKL2i34nkNJioj4Kkoj234j%jij1kjojsdffds98giojerNNjasndasiNjasdnJAjnasdkjnFoFjoFJOIAASD8990adsaaDknnkngs.v_Ko6HZjrahbihLbw2Bm7EuslEC2SSHXNK79rDbD9qIIVYxPjCsubsdfkyAWDIoJHwjkM9TtssYS-1Cjd_xkXghfILuDZpzLsHV6rF20J4n3eUTrsnmLDHK6UB5N3yK2LYoF1UoFrsiyWenfqELfE4Gx5wlfmsylTS1foS2CWRrT1ccqmJBinWiY6JNUS-0gg-2Aecf_VJ63RD9308sBKy1DUsBeje9yG8w2YpYsAqKIlMTC-FqLLpHlKe4LZxcveiqSF4J6PgvcLSPTMmg7-Li_8m41O-wfU1zwSpS1SJ73RJNg-kvRZ1y1ll8ExqXjZkazRDVkYVo6yu5AXi1Onl6FqBLA

通过 JWT.io 检查令牌会给我一个正确的有效载荷。

现在是 $key 部分。我已经从 Google API 控制台下载了默认服务帐户 JSON 文件。如果我使用看起来像这样的“private_key”:

-----BEGIN PRIVATE KEY-----\n[VERY_LONG_PRIVATE_KEY]\n-----END PRIVATE KEY-----\n

我收到此错误:

openssl_verify(): supplied key param cannot be coerced into a public key

我在 *** 上找到了一个答案,这可以用来将私钥转换为公钥:

$private_key = openssl_pkey_get_private($c->serviceAccount->private_key);
$details = openssl_pkey_get_details($private_key);
$public_key = $details['key']

因此,如果我改用 $public_key,则会收到另一个错误,说明如下:

Uncaught exception 'DomainException' with message 'OpenSSL unable to verify data: error:0906D06C:PEM routines:PEM_read_bio:no start line

公钥如下:

-----BEGIN PUBLIC KEY-----\n[VERY_LONG_KEY]\n-----END PUBLIC KEY-----\n

所以看起来它应该可以工作。但事实并非如此。 RS256算法也是正确的。

任何帮助表示赞赏!

【问题讨论】:

【参考方案1】:

我在使用 Node.js 读取我的私钥时遇到了同样的错误 Error: error:0906D06C:PEM routines:PEM_read_bio:no start line

原来问题在于 Google Cloud 将 \n 转换为 \\n。当我将它转换回\n 时,它起作用了。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const bigquery = require('@google-cloud/bigquery');

const config = functions.config();
admin.initializeApp(config.firebase);
const firestore = admin.firestore();

const sanitizePrivateKey = (key) =>
  key.replace(/\\n/g, '\n');

/* firebase converts \n to \\n, we have to convert it back */
if (config.credentials) 
  config.credentials.private_key = sanitizePrivateKey(config.credentials.private_key);


const bigqueryClient = bigquery(
  projectId: 'screencastify-staging',
  // eslint-disable-next-line
  credentials: config.credentials,
);

【讨论】:

以上是关于Firebase PHP JWT“OpenSSL 无法验证数据:错误:0906D06C:PEM 例程:PEM_read_bio:no start line”的主要内容,如果未能解决你的问题,请参考以下文章

如何为 php-jwt 生成密钥对?

Apple 登录“invalid_client”,使用 PHP 和 openSSL 签署 JWT 进行身份验证

PHP Firebase 帮助 - 设置 JWT

在 Angular 6 中解码 firebase/php-jwt

Firebase JWT 库无法验证 Python JWT 令牌

php firebase/php-jwt token验证