我正在尝试用 C 对文件/消息进行数字签名并验证 PHP 中的签名。我可以在 C 中正确验证它,但是当我尝试导入签名并在 PHP 中验证它时它失败了。
我正在使用这种方法在 C 中签署消息:
bool RSASign( RSA* rsa,
const unsigned char* Msg,
size_t MsgLen,
unsigned char** EncMsg,
size_t* MsgLenEnc) {
EVP_MD_CTX* m_RSASignCtx = EVP_MD_CTX_create();
EVP_PKEY_assign_RSA(privkey, rsa);
if (EVP_DigestSignInit(m_RSASignCtx,NULL, EVP_sha256(), NULL,privkey)<=0) {
return false;
}
if (EVP_DigestSignUpdate(m_RSASignCtx, Msg, MsgLen) <= 0) {
return false;
}
if (EVP_DigestSignFinal(m_RSASignCtx, NULL, MsgLenEnc) <=0) {
return false;
}
*EncMsg = (unsigned char*)malloc(*MsgLenEnc);
if (EVP_DigestSignFinal(m_RSASignCtx, *EncMsg, MsgLenEnc) <= 0) {
return false;
}
EVP_MD_CTX_free(m_RSASignCtx);
return true;
}
正如我所说,如果我尝试仅在 C 中验证此签名,则它工作正常。私钥是在代码中使用以下代码行获得的:
pin = (char *) getpass("Enter PIN: ");
rc = PKCS11_login(slot, 0, pin);
authkey = PKCS11_find_key(&certs[0]);
如果有必要,我可以发布有关如何获得插槽的代码,但我认为现在没有必要。
我正在尝试使用以下代码验证 PHP 中的签名:
function isOriginal() {
$signature = base64_decode("HZwn2Zz4ir5Isvvo+fEj8IFydQs/tuW3I6HPzadHMIq+i5qCBURXqK/B5X1gYyoCPyHzgyY/zJI1skoFdKwPwx6ySEwLBZ5QTFsxp56jGi/UZgXu8X+jfvHfss89VhqcIxiZdklhZtlf5sMdJ045KbfvHDeAyfXj2C/3Nvk8IQMR+q3eUGAkiEZJIWpivp5WufrjFlsmKRdDm8j2szJPtIVipyj1AwIYkiAJOggC4JWd3LWn8C4bt84ys2CezFbc7BDckLe2IGBkaDMsCTr8PE0SP81npqHd9CyfvU4zd5LyXkBNZqz3QnAN19iI0b5EdUeJj3UQ83gmuugGy1088g==");
$plaintext = "My secret message.";
$id = openssl_pkey_get_public(MY_PUB_CERT_IN_A_CONST_STR);
echo (openssl_verify($plaintext, $signature, $id, OPENSSL_ALGO_SHA256) ? 'verified' : 'unverified');
}
结果相同。有没有人知道它为什么会失败?AFAIU 我在 C 和 PHP 中使用相同的算法。任何帮助表示赞赏。
您可能还想知道为什么我要尝试这样做以及为什么我不在 PHP 中分别使用 PHP 函数和 C 中的 C 函数进行验证。这是因为我想使用只能从 .so 文件中访问的 A3 令牌对消息和文件进行签名C. AFAIU PHP 没有任何使用 A3 令牌签署文件的功能。
如果有任何选项可以使用来自 PHP 的 A3 令牌来签署文件,我真的很想知道。
临摹微笑