【问题标题】:Is there any way to generate PSS padded signatures in PHP?有没有办法在 PHP 中生成 PSS 填充签名?
【发布时间】:2012-01-18 04:29:04
【问题描述】:

在 PHP 中,我想用 PSS 填充和 SHA512 的摘要签署一些文档。

根据http://www.php.net/manual/en/function.openssl-sign.php 的文档,我可以根据需要设置摘要,方法是使用字符串,例如

openssl_sign($text-to-sign,$binary_signature,$privkey,"sha512");

但是,我看不到任何设置填充的方法。

谁能帮助我了解如何使用 RSA-PSS 填充样式对文本进行签名,如 PKCS #1 的 2.1 版所示?

【问题讨论】:

    标签: php encryption openssl rsa signing


    【解决方案1】:

    我和你有同样的需求,但在 2019 年(我想我们现在有了更好的库;)

    正如您已经发现的那样,方法是使用phpseclib,它现在在 Debian Stretch 中是 2.0 版。

    签名生成

    这是我用来签署一些二进制数据的代码,使用 8192 RSA 密钥,带有 PSS 填充和 SHA512 哈希函数:

    require "/usr/share/php/phpseclib/autoload.php";
    use phpseclib\Crypt\RSA;
    
    // INPUT DATA
    $privkey = "...";   // I used a RSA private key in PEM format, generated by openssl, but phpseclib supports many formats...
    $mydata = "...";    // I generated some binary bytes here...
    
    // SIGNING
    $rsa = new RSA();
    if ($rsa->loadKey($privkey) != TRUE) {
        echo "Error loading private key";
        return;
    }
    $rsa->setHash("sha512");
    $rsa->setMGFHash("sha512"); // This NEEDS to be set, or the default will be used
    $rsa->setSignatureMode(RSA::SIGNATURE_PSS); // This doesn't need to be set, as it is already the default value
    $signatureBytes = $rsa->sign($mydata);
    

    $signatureBytes 是一个 二进制 字符串(或字节数组,正如您在 C/C++/C# 中所称的那样)。它没有任何编码,并且可能包含 NULL 字节。这是你想要的签名。

    旁注:安装 php-gmp 几乎是必需的,否则签名时间会非常缓慢。 Here 有一些基准测试。

    使用 OpenSSL 进行签名验证

    openssl dgst -sha512 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -verify pubkey.pem -signature signature.bin 明文数据.dat

    详细地说,-sigopt rsa_pss_saltlen:-1 告诉openssl 使用与散列算法大小相匹配的盐长度。 (this is what the Microsoft APIs do, and there's no way to change that behavior)

    使用 C++/CLI (.NET) 进行签名验证

    为了能够在 .NET 世界中使用 RSA 公钥,而不使用任何其他库,您需要首先使用 openssl 将其导出为 BLOB 格式:

    openssl rsa -pubin -inform PEM -in pubkey.pem -outform "MS PUBLICKEYBLOB" -out pubkey.blob

    然后,您需要 .NET 4.6,以及新的 RSACng CryptoProvider。

    这就是代码:

    // Import the public key (as BLOBDATA)
    RSACryptoServiceProvider^ rsaCsp = gcnew RSACryptoServiceProvider();
    rsaCsp->ImportCspBlob(pubkey);
    RSAParameters rsaParams = rsaCsp->ExportParameters(false);
    
    RSA^ rsa = gcnew RSACng();
    rsa->ImportParameters(rsaParams);
    array<Byte>^ dataBytes = ...;
    array<Byte>^ signatureBytes = ...;
    bool signIsValid = rsa->VerifyData(dataBytes, signatureBytes, HashAlgorithmName::SHA512, RSASignaturePadding::Pss);
    

    【讨论】:

      【解决方案2】:

      为了不成为“那个家伙”,我想我会回答这个问题,因为这确实会出现在 Google 和所有内容中;)

      我可以通过http://phpseclib.sourceforge.net/ 获得 PSS 填充 到目前为止,我还没有让它与 OpenSSL 或 LibTomCrypt 互操作,但是.. 我可能只是配置错误。

      我相信你会有更好的运气,未来的人!

      -CPD

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-16
        • 1970-01-01
        • 1970-01-01
        • 2021-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多