如何使用openssl验证php中的签名?如何使用SecKey概念验证iOS中生成的签名

如何使用openssl验证php中的签名?如何使用SecKey概念验证iOS中生成的签名,php,ios,openssl,Php,Ios,Openssl,我的iOS应用程序是用swift编写的,它使用SecKeyCreateRandomKey为私钥生成密钥对(带有kSecAttrKeyTypeRSA和2048位属性),并使用SecKeyCopyPublicKey检索公钥。我使用SecKeyCreateSignature使用私钥对数据进行签名 我将签名转换为字符串:signature?.base64EncodedString() 我使用SecKeyCopyExternalRepresentation将公钥SecKey结构转换为字符串,并将其转换为k

我的iOS应用程序是用swift编写的,它使用SecKeyCreateRandomKey为私钥生成密钥对(带有kSecAttrKeyTypeRSA和2048位属性),并使用SecKeyCopyPublicKey检索公钥。我使用SecKeyCreateSignature使用私钥对数据进行签名

我将签名转换为字符串:signature?.base64EncodedString()

我使用SecKeyCopyExternalRepresentation将公钥SecKey结构转换为字符串,并将其转换为key.base64EncodedString()

我(使用HTTPPOST和JSON)将数据、公钥和签名发送到我的服务器。服务器将此信息存储在数据库中

稍后,我的应用程序的另一个实例查询服务器,服务器用相关数据、签名和公钥进行响应

在从服务器返回的过程中,我使用SecKeyCreateWithData恢复公钥SecKey结构,然后应用程序使用签名和使用SecKeyVerifySignature的公钥验证数据(使用.rsAssignatureMessagePKCS1v15SHA512 algo)

这是完美的。签名、发送、存储。。。请求、检索、验证。我知道,因此,我没有问题来回传送数据,没有问题让苹果的核心安全功能正常工作。。。在应用程序端。然而:

我在PHP端验证签名时遇到困难。理想情况下,我希望在PHP服务器逻辑的各个点上验证签名、数据和公钥。我尝试使用openssl\u验证失败。我试过(从数据库中读取):

我不确定我做得是否正确,我无法通过“强制”错误消息openssl_verify():提供的密钥参数无法强制转换为公钥

虽然文档声明verify函数特别允许$key也作为密钥字符串传递,但没有提供示例。所有示例都涉及文件和证书等。我将密钥加载到字符串中,我提供的是iOS没有生成的“盔甲”——我缺少什么?非常感谢您的帮助。

我已经找到了一个解决方案(但仍在寻找openssl\u验证解决方案)。 我发现了一个名为phpseclib的php库。我使用composer安装了它(macos),包括:

require 'vendor/autoload.php';
use phpseclib\Crypt\RSA;
然后,我将一个openssl_验证代码行替换为:

$rsa = new RSA();
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$rsa->setHash('sha512');
$rsa->loadKey("-----BEGIN PUBLIC KEY-----\n" . trim($publicKey) . "\n-----END PUBLIC KEY-----");
$ok = $rsa->verify($data, $signature);

工作起来很有魅力。如果有人向我展示如何使用openssl_进行验证,我将很乐意迁移。我看到一些关于这个库过时的噪音。

我遇到了同样的问题。我发现不像使用
SecKeyCopyExternalRepresentation()
那样导出公钥:

CFDataRef publickeyBytes;
SecItemImportExportKeyParameters keyParams = { .version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION, .passphrase = @"" };
SecItemExport( publickey, kSecFormatOpenSSL, 0, &keyParams, &publickeyBytes );

给了我一个公钥,它的格式可以在PHP端使用openssl导入(在base64编码和添加
----开始公钥---
&
----结束公钥---

你能把你的Swift代码和示例数据一起发布吗?愚蠢的问题,您是否尝试过
$key=“----开始公钥------\n”。区块分割($publicKey,76,“\n”)。“----结束公钥------”不确定它对空白有多敏感。我试过了,各种各样的味道。我在猜测这个问题;函数需要:某些特定的密钥类型、签名类型、算法类型等。可能需要将字符串密钥转换为某些内部表示形式。。。搜索太多,没有足够的示例/文档。但是,既然我有一个有效的解决方案,我就放手了;)(而且,因为我在swift中没有问题,所以我没有发布该代码…)可能没有问题,但它可能会帮助某人重新创建问题。感谢您的反馈。下一步我回到代码中时,我将尝试@SpencerNielsen--SecItemExport方法不支持iOS
CFDataRef publickeyBytes;
SecItemImportExportKeyParameters keyParams = { .version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION, .passphrase = @"" };
SecItemExport( publickey, kSecFormatOpenSSL, 0, &keyParams, &publickeyBytes );