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条)

报告相同问题?