gpt4 book ai didi

php - 在 C 和 PHP 中进行数字签名的正确算法是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:07 24 4
gpt4 key购买 nike

我正在尝试在 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==");
$publicRSAKey = "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQAB-----END PUBLIC KEY-----";

$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');
}

这失败了。我也尝试过使用 PHPSECLIB:

function isOriginal() {
$signature = base64_decode("HZwn2Zz4ir5Isvvo+fEj8IFydQs/tuW3I6HPzadHMIq+i5qCBURXqK/B5X1gYyoCPyHzgyY/zJI1skoFdKwPwx6ySEwLBZ5QTFsxp56jGi/UZgXu8X+jfvHfss89VhqcIxiZdklhZtlf5sMdJ045KbfvHDeAyfXj2C/3Nvk8IQMR+q3eUGAkiEZJIWpivp5WufrjFlsmKRdDm8j2szJPtIVipyj1AwIYkiAJOggC4JWd3LWn8C4bt84ys2CezFbc7BDckLe2IGBkaDMsCTr8PE0SP81npqHd9CyfvU4zd5LyXkBNZqz3QnAN19iI0b5EdUeJj3UQ83gmuugGy1088g==");
$publicRSAKey = "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQAB-----END PUBLIC KEY-----";

$rsa = new RSA();
$rsa->loadKey($publicRSAKey);
$rsa->setHash('sha256');

$plaintext = "My secret message.";

echo ($rsa->verify($plaintext, $signature) ? 'verified' : 'unverified');
}

结果相同。有谁知道它为什么失败? AFAIU 我在 C 和 PHP 中使用相同的算法。任何帮助表示赞赏。

您可能还想知道为什么我要尝试这样做以及为什么我不在 PHP 中分别使用 PHP 函数和 C 中的 C 函数进行验证。这是因为我想使用只能从 .所以 C 中的文件。AFAIU PHP 没有任何使用 A3 token 对文件进行签名的函数。

如果有任何选项可以使用 PHP 中的 A3 token 对文件进行签名,我真的很想知道。

最佳答案

对于 phpseclib,在 $rsa->verify() 之前执行此操作:

$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);

要使用 X.509 证书做到这一点...

$x509 = new \phpseclib\File\X509;
$x509->loadX509('...');
$rsa = $x509->getPublicKey();

关于php - 在 C 和 PHP 中进行数字签名的正确算法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57281575/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com