dra87370 2018-11-15 14:09 采纳率: 100%
浏览 1234
已采纳

如何在PHP中实现相同的签名生成?

我有以下示例代码,用于使用自签名证书生成签名:

public static String generateSignature(String data) throws Exception {

        System.out.println("@@inside generateSignature: " + data);

        String signature;

        String jksFilepath = "E:\\test.jks";

        try {
            // Adding Security Provider for PKCS 12
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            // Setting password for the e-Token

            // logging into token
            ks = KeyStore.getInstance("jks");


            FileInputStream fileInputStream = new FileInputStream(jksFilepath);

            // Loading Keystore
            // System.out.println("loading keystore");
            ks.load(fileInputStream, JKSPassword);
            Enumeration<String> e = ks.aliases();

            while (e.hasMoreElements()) {
                alias = e.nextElement();
                // System.out.println("Alias of the e-Token : "+ alias);

                UserCert = (X509Certificate) ks.getCertificate(alias);

                UserCertPubKey = (PublicKey) ks.getCertificate(alias).getPublicKey();

                // System.out.println("loading Private key");
                UserCertPrivKey = (PrivateKey) ks.getKey(alias, JKSPassword);
            }

            // Method Call to generate Signature
            signature = MakeSignature(data);

            return signature;

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("generateSignature" + e.getCause());
            throw new Exception();
        }

    }

    private static String MakeSignature(String data) {

        System.out.println("@@inside MakeSignature...");

        try {
            PrivateKey privateKey = (PrivateKey) ks.getKey(alias, JKSPassword);
            myPubCert = (X509Certificate) ks.getCertificate(alias);
            Store certs = new JcaCertStore(Arrays.asList(myPubCert));

            CMSSignedDataGenerator generator = new CMSSignedDataGenerator();

            generator.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA256withRSA", privateKey, myPubCert));

            generator.addCertificates(certs);

            CMSTypedData data1 = new CMSProcessableByteArray(data.getBytes());

            CMSSignedData signed = generator.generate(data1, true);

            BASE64Encoder encoder = new BASE64Encoder();

            String signedContent = encoder.encode((byte[]) signed.getSignedContent().getContent());

            String envelopedData = encoder.encode(signed.getEncoded());

            return envelopedData;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("MakeSignature ==" + e.getCause());
            return "";
        }
    }

也有一些相关的功能,但为了简短起见我没有添加。现在,我想使用PHP进行完全相同的操作,但是JKS不能在PHP上作为Java的密钥库使用。我尝试使用具有不同加密方法集的open_ssl函数,但是我没有得到与通过此Java代码获得的预期结果相同的预期结果(“不相同”是关于所生成签名的比特率和长度)。

有人可以帮我在PHP中实现相同的签名生成吗?

  • 写回答

2条回答 默认 最新

  • dongshen7407 2018-11-19 06:45
    关注

    I think the PHP official document is very clear: http://php.net/manual/en/function.openssl-csr-new.php

    Example #1 Creating a self-signed certificate

    <?php
    $dn = array(
        "countryName" => "GB",
        "stateOrProvinceName" => "Somerset",
        "localityName" => "Glastonbury",
        "organizationName" => "The Brain Room Limited",
        "organizationalUnitName" => "PHP Documentation Team",
        "commonName" => "Wez Furlong",
        "emailAddress" => "wez@example.com"
    );
    
    // Generate a new private (and public) key pair
    $privkey = openssl_pkey_new(array(
        "private_key_bits" => 2048,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    ));
    
    // Generate a certificate signing request
    $csr = openssl_csr_new($dn, $privkey, array('digest_alg' => 'sha256'));
    
    // Generate a self-signed cert, valid for 365 days
    $x509 = openssl_csr_sign($csr, null, $privkey, $days=365, array('digest_alg' => 'sha256'));
    
    // Save your private key, CSR and self-signed cert for later use
    openssl_csr_export($csr, $csrout) and var_dump($csrout);
    openssl_x509_export($x509, $certout) and var_dump($certout);
    openssl_pkey_export($privkey, $pkeyout, "mypassword") and var_dump($pkeyout);
    
    // Show any errors that occurred here
    while (($e = openssl_error_string()) !== false) {
        echo $e . "
    ";
    }
    

    Then you can call openssl_sign: http://php.net/manual/en/function.openssl-sign.php , use the generated private key to sign.

    If you want to use the Java(JKS)'s key in PHP code, you should export the keys first, and then use PHP function load the keys.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格