You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程使用YubiKey 5A签名PDF?现有代码待完善

问题:使用YubiKey安全密钥签名PDF的实现困境

我需要实现使用YubiKey 5A及yubico-piv-tool库完成PDF签名的功能,参考多方资料编写了代码,但未达成预期效果。

void signPDF(const char* pdfFilePath, const char* yubikeyPIN) {
    // Open PDF file
    HPDF_Doc pdf = HPDF_New(error_handler, NULL);
    if (!pdf) {
      fprintf(stderr, "Error: Cannot create PDF object\n");
      return;
    }

    // Add a page to the document
    HPDF_Page page = HPDF_AddPage(pdf);

    // Set the font and size
    HPDF_Font font = HPDF_GetFont(pdf, "Helvetica", NULL);
    HPDF_Page_SetFontAndSize(page, font, 24);

    // Write some text
    HPDF_Page_BeginText(page);
    HPDF_Page_TextOut(page, 50, 700, "Not so Random!");
    HPDF_Page_EndText(page);

    // Save PDF content to stream
    if (HPDF_OK != HPDF_SaveToStream(pdf)) {
      fprintf(stderr, "Error: Cannot save PDF to stream\n");
      HPDF_Free(pdf);
      return;
    }

    // Get the size of the stream
    HPDF_UINT32 contentLen = HPDF_GetStreamSize(pdf);

    // Allocate memory for the content
    HPDF_BYTE *content = (HPDF_BYTE *)malloc(contentLen);

    // Perform signing operation using YubiKey's PIV
    ykpiv_state *state;
    if (ykpiv_init(&state, 0) != YKPIV_OK) {
      fprintf(stderr, "Error: Cannot initialize YubiKey PIV\n");
      return;
    }

    ykpiv_rc res = ykpiv_connect(state, NULL);
    if (res != YKPIV_OK) {
      fprintf(stderr, "Error: ykpiv_connect failed with code %d\n", res);
      return;
    }

    int tries;
    res = ykpiv_verify(state, yubikeyPIN, &tries);
    if (res != YKPIV_OK) {
      fprintf(stderr, "Error: Cannot authenticate with YubiKey\n");
      return;
    }

    size_t signatureLen = YKPIV_MAX_SIGNATURE_SIZE;
    unsigned char signature[YKPIV_MAX_SIGNATURE_SIZE];
    res =
        ykpiv_sign_data(state, content, contentLen, signature, &signatureLen,
                        YKPIV_ALGO_ECCP256, YKPIV_KEY_SIGNATURE);
    if (res != YKPIV_OK) {
      fprintf(stderr, "Error: Cannot sign PDF content. Error code: %d\n", res);
      ykpiv_done(state);
      HPDF_Free(pdf);
      return;
    }

    // Save the signed PDF file
    if (HPDF_SaveToFile(pdf, "signed_example.pdf") != HPDF_OK) {
      fprintf(stderr, "Error: Cannot save signed PDF file.\n");
      return;
    }

    printf("PDF file signed successfully.\n");
}

上述代码可创建单页PDF文档(后续计划直接加载本地PDF),也能通过YubiKey中的私钥完成内容签名,但无法将签名内容正确追加到PDF的对应字节范围。

我尝试过PoDoFo库,但它要求提前获取私钥,违背了YubiKey密钥不可导出的原则;从零实现PDF签名逻辑又过于复杂。请问接下来该尝试什么方案?不限编程语言。


内容的提问来源于stack exchange,提问作者Hasnain Raza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:07:50