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

Mac Security框架下OpenVPN客户端RSA PSS签名算法选型问题

OpenVPN客户端C++外部PKI签名:RSA_PKCS1_PSS_PADDING算法适配问题

我正在为OpenVPN客户端实现C++外部PKI签名方法,需要使用RSA_PKCS1_PSS_PADDING算法,但苹果Security框架无直接对应方法。以下是我的签名函数:

void MacStore::sign(const std::string &data, std::string &sig, const std::string &algorithm,
                    const std::string &hashalg, const std::string &saltlen) {
    SecKeyAlgorithm alg;
    if (!hashalg.empty()) {
        alg = kSecKeyAlgorithmRSASignatureDigestPSSSHA256;
    } else {
        alg = kSecKeyAlgorithmRSASignatureMessagePSSSHA1;
    }
    openvpn::BufferAllocated signdata(256, openvpn::BufferAllocated::GROW);
    openvpn::base64->decode(signdata, data);
    SecKeyRef pkey;
    OSStatus status = SecIdentityCopyPrivateKey((SecIdentityRef)identity, &pkey);
    if (status) {
        // error
        return;
    }
    auto isSupported = SecKeyIsAlgorithmSupported(pkey, kSecKeyOperationTypeSign, alg);
    std::cout << (isSupported ? "supported" : "not supported") << std::endl;
    auto dataToSign = CFStringCreateWithCString(nullptr, buf_c_str(signdata), kCFStringEncodingASCII);
    auto dataToSignPtr = CFStringCreateExternalRepresentation(nullptr, dataToSign, kCFStringEncodingASCII, 0);

    CFErrorRef err = nullptr;
    auto signature = SecKeyCreateSignature(pkey, alg, dataToSignPtr, &err);
    if (err) {
        return;
    }

    SecCertificateRef cert;
    SecIdentityCopyCertificate((SecIdentityRef)identity, &cert);
    SecKeyRef pub;
    SecCertificateCopyPublicKey(cert, &pub);

    int signatureLength = CFDataGetLength(signature);
    openvpn::BufferAllocated signer(signatureLength, openvpn::BufferAllocated::ARRAY);
    auto range = CFRangeMake(0, signatureLength);
    CFDataGetBytes(signature, range, signer.data());
    signer.set_size(signatureLength);

    CFRelease(signature);
    CFRelease(dataToSign);

    sig = openvpn::base64->encode(signer);
    std::cout << "SIGNATURE[" << signatureLength << "]: " << signer.c_str() << std::endl;
}

连接服务器时,服务器日志输出如下:

// Verifies certificate - OK
OpenSSL: error:02000087:rsa routines::salt length recovery failed
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 OpenSSL: error:1C880004:Provider routines::RSA lib
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 OpenSSL: error:0A00007B:SSL routines::bad signature
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 TLS_ERROR: BIO read tls_read_plaintext error
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 TLS Error: TLS object -> incoming plaintext read error
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 TLS Error: TLS handshake failed
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 Fatal TLS error (check_tls_errors_co), restarting
Dec 09 12:51:38 server openvpn[29669]: 10.31.154.84:50843 SIGUSR1[soft,tls-error] received, client-instance restarting

我想咨询应选择哪个SecKeyAlgorithm才能生成有效的RSA签名?

更新:使用相同待签名数据的验证方法也返回false(签名无效)。


内容的提问来源于stack exchange,提问作者int64_t Papich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:55:20