我有一个以字符串形式存储在数据库中的公钥.生成库表示它是RSA 2048公钥.以下是存储的公钥的示例:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmHPAou1FpNAoLwF/mL0rei8QcC+LvKIYteEHOpxGibI6PNQ8kSpB7WNPJT2wM+B0+DT04L5LBi78PSo1UQO3umYEhHbAsKuNBV3CR8NGfUsWzSkgIzkbTCsELWkJT50foBT4YmBKEe6W8Ai2+3yzvMtic8RtBel73zS3dIdUUGaf7SMPtva+XDZTozRNiyligPh0nDgHcj6OQAtCxfTogLKukwaEPyWA06nQ68pMsxzzHqUZl5HJuDJRphAtOc2ZRFXZ1xaxVMO2D7UnkFA5q00UBW/i+KzkhgtNkLI8j2jiBim3IozRwpjQJvFsKoi29WDWPXcgtTU6k9kSmJBIqQIDAQAB

我有一个由同一个库生成的数据字符串和签名.根据文档,该签名是RSA PKCS#1v1.5 SHA 256签名.

数据字符串:

{"username":"user@example.com","requestTime":"1679669234"}

签署:

PiXcXFykgtOZY+tpmmXqt39VHwURd5NSIGL0U+TEj+qS6QwIT4Eh4W3fKYfIXwZGDu6Rdsu2PQxqBMhEQe7H7C0nq6ssih74MLavxpLuGPxmlZJ/EN2/m2fhLweerjS6U1uMIDcKE6cZgSD6z+KfkuWnKssM5yuMEkdztL5ef0Ay6Il0jXGayp+tLMGxGZaJLv31PRmYoK3c68buGphKV0hnj2y6+rKsoPfn+sVDxInH40oNcxF2zU+Y3ed9pW+/VOpnkTE9MoSNthNvwjNpRFJr4Awx7mKmOGe3dvC3yZ+iZ/lT892pTSwqo1O2mtXskbsUe1+xEfrzbi1/0ejy/g==

我一直在try 使用openssl_verify来验证此签名,但甚至无法使用openssl_pkey_get_public成功地解析公钥.我try 了以下几种不同的版本:

$publickey = "-----BEGIN RSA PUBLIC KEY-----\n".$publickey."\n-----END RSA PUBLIC KEY-----";
$pkey = openssl_pkey_get_public($publickey);

我已经try 了-----BEGIN RSA PUBLIC KEY----------BEGIN PUBLIC KEY-----的不同版本,不过我相信RSA版本是正确的.在转到openssl_pkey_get_public之前,我也try 过使用chunk_split($publickey, 64, "\n")来拆分行.

每次try 后,openssl_error_string()将返回以下内容:

error:0909006C:PEM routines:get_name:no start line

我不明白为什么会是这样.有谁能帮我验证这个签名吗?

虽然我希望避免额外的PHP库,但如果我必须安装一个PHP库,比如phpseclib,我会这样做的.

推荐答案

这是所谓的SPKI(主体公钥标识符).这就是在PEM报头行中没有RSA的那个,也就是只有公钥.

也许问题在于PEM的 struct 不正确.

例如,您可以try 以下操作:

$publickey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmHPAou1FpNAoLwF/mL0rei8QcC+LvKIYteEHOpxGibI6PNQ8kSpB7WNPJT2wM+
B0+DT04L5LBi78PSo1UQO3umYEhHbAsKuNBV3CR8NGfUsWzSkgIzkbTCsELWkJT50foBT4YmBKEe6W8Ai2+3yzvMtic8RtBel73zS3dIdUUGaf7SMPtva+XD
ZTozRNiyligPh0nDgHcj6OQAtCxfTogLKukwaEPyWA06nQ68pMsxzzHqUZl5HJuDJRphAtOc2ZRFXZ1xaxVMO2D7UnkFA5q00UBW/i+KzkhgtNkLI8j2jiBi
m3IozRwpjQJvFsKoi29WDWPXcgtTU6k9kSmJBIqQIDAQAB";
preg_replace("(.{64})", "\1\r\n", $publickey);
$publickey = "-----BEGIN PUBLIC KEY-----\r\n".$publickey."\r\n-----END PUBLIC KEY-----";
$pkey = openssl_pkey_get_public($publickey);

请注意,PEM文件确实需要Base64,但正式的行限制是64个字符.较早的解析器可能要求使用CR/LF而不是仅使用LF,因此字符串中的\r\n.


因为你对它很好,签名验证:

$data = '{"username":"user@example.com","requestTime":"1679669234"}';
$sig = "PiXcXFykgtOZY+tpmmXqt39VHwURd5NSIGL0U+TEj+qS6QwIT4Eh4W3fKYfIXwZGDu6Rdsu2PQxqBMhEQe7H7C0nq6ssih74MLavxpLuGPxmlZJ/EN2/m2fhLweerjS6U1uMIDcKE6cZgSD6z+KfkuWnKssM5yuMEkdztL5ef0Ay6Il0jXGayp+tLMGxGZaJLv31PRmYoK3c68buGphKV0hnj2y6+rKsoPfn+sVDxInH40oNcxF2zU+Y3ed9pW+/VOpnkTE9MoSNthNvwjNpRFJr4Awx7mKmOGe3dvC3yZ+iZ/lT892pTSwqo1O2mtXskbsUe1+xEfrzbi1/0ejy/g==";
$res = openssl_verify($data, base64_decode($sig), $pkey, OPENSSL_ALGO_SHA256);

Php相关问答推荐

在WooCommerce中处理客户总支出中的退款

Laravel迁移返回SQL错误,但SQL有效且工作正常

我需要多个SELECT语句的结果(使用由php ECHO创建的表中显示的Limit(X)

在WooCommerce产品中按类型对产品属性术语进行分类以供显示

在没有symfony应用程序的情况下使用安全Bundle 包时,缺少配置构建器类

根据产品类型显示或隐藏WooCommerce管理产品自定义字段

PHP空数组定义与开始或结束逗号

从目录文件夹中获取文件并追加到 Select 下拉列表(选项)-wordpress/wc

服务器迁移后无法上载文件-可能存在权限问题

函数存储到变量中

在WooCommerce上设置简单和可变产品的最小订单量

WooCommerce中特定付款方式的变更订单预留库存时间

如何在codeigniter中将order_by RAND与下面的代码一起使用

在 WooCommerce 订阅续订订单中设置送货方式

htaccess Rewriterule 无法以任何方式工作

如何通过帖子自定义元数据进行查询

正则表达式请帮我从内容中找到这个词

为什么 ECDSA 384 签名验证在 GO 中失败,但在 PHP 中却没有?

如何使 Wordpress Woocommerce 自定义输入字段成为必填字段

基于其他数组创建多维数组 struct