猿问

在 C 中进行数字签名并在 PHP 中进行veryfing 的正确算法是什么?

我正在尝试用 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 令牌来签署文件,我真的很想知道。


POPMUISE
浏览 171回答 1
1回答

临摹微笑

对于 phpseclib,请在此之前执行此操作$rsa->verify():$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);要使用 X.509 证书执行此操作...$x509 = new \phpseclib\File\X509;$x509->loadX509('...');$rsa = $x509->getPublicKey();
随时随地看视频慕课网APP
我要回答