如何用PHP中的RSA私钥加密数据?

问题描述 投票:0回答:1

目前我正在使用php进行基于财务的应用程序。我与第三方api集成以获取用户数据。

基于集成,它们使用签名和有效负载进行身份验证。

根据文件,我为我的观点做了一切正确,但我得到了回应

SignatureDoesNotMatch我们计算的请求签名与您提供的签名不符。

根据文件:

计算签名:必要时,请求必须由发件人签名。请求的签名计算如下:

  1. 将有效负载XML压缩为单行,如下所示:2。删除XML声明3.删除所有注释4.删除所有换行符5.Normalise spaces

6)生成压缩有效负载的SHA1摘要。 7)Base16编码生成的SHA1摘要。 8)使用Perfios提供的RSA私钥加密编码的摘要。 9)Base16编码加密的摘要。

我的脚本在这里:

$condense_payload ='<payload><vendorId>test</vendorId><txnId>dummyApplicationId</txnId><emailId>'.$emailid.'</emailId><destination>netbankingFetch</destination><returnUrl>https://www.google.com</returnUrl></payload>';


$condense_payload_updated = trim(preg_replace('/(?<=\>)(\r?\n)|(\r?\n)(?=\<\/)/', $condense_payload));


$payload ='
<payload>
<vendorId>test</vendorId>
<txnId>dummyApplicationId</txnId>
<emailId>'.$emailid.'</emailId>
<destination>netbankingFetch</destination>
<returnUrl>https://www.google.com</returnUrl>
</payload>';

/* Convert to Sha1 */
$sha1_convert = sha1($condense_payload_updated);

/* Convert to Hex (base16) */
$first_base16_convert=bin2hex($sha1_convert);


$fp =  fopen("private_key", "r");

$private_key_string = fread($fp, 8192);

fclose($fp);

/* Convert to private key */
$private_key = openssl_get_privatekey($private_key_string);

$encrypted_private="";



/* Encrypt digest using key */

openssl_private_encrypt($first_base16_convert, $encrypted_private, $private_key, OPENSSL_PKCS1_PADDING);
/* Convert to Hex (base16) */
$signature=bin2hex($encrypted_private);

所以这里生成了有效负载和签名,并使用post方法发送url:

<html>
    <body onload='document.autoform.submit();'>
        <form name='autoform' method='post' action='https://demo.perfios.com/KuberaVault/insights/start'>
            <input type='hidden' name='payload' value='<?php echo $payload; ?>' />
            <input type='hidden' name='signature' value='<?php echo $signature; ?>'/>
    </body>
</html>

所以最后我得到了:

SignatureDoesNotMatch我们计算的请求签名与您提供的签名不符。

Api支持团队提供了java示例代码,在编译和运行java时,其工作正常。

这里java代码:

   package javaapplication1;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.security.Key;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;

import javax.crypto.Cipher;

import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.util.encoders.Hex;

public class JavaApplication1 {
    static String email = "[email protected]";
    static String server = "demo.test.com";
    public static String vendor = "test";
    public static String returnURL = "https://www.google.com";


    static String privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" + 
            "MIIEpQIBAAKCAQEAx76oeNWYPkAbbSPyvJdfgfdgcPkQvAMvIHCPgY9yNdN/qsYMHytyit\n" + 
            "xdO0aTatgfS/ig4zmqKFVpC9o2YMyQ7E1FYNcl/ev++r4nV+qVXA1OKcsSv4Kbj/\n" + 
            fgdfg"iNwxGmnhBsRDswY/dEZZDN9RisRpo9NRSOskGRv+nLEA2dLgj0/f9SSzykz3cxAP\n" + 
            "bq6bV0unie5C8r6RALj+hTLU7B7QF88SkDsFx0/TYQe4H9QJtFMWJtOnhumY5Ku6\n" + 
            "CL4OdZrtz71y4ji8IxQxv2nyqdfgfd0JwYQ4rG84uzJQeRQf2RaJLhnSdfQnonDkP7L1z\n" + 
            "NSizzi8VgHI+GVIo9FrLj7DVo+fFzMucbsvvNQIDAQABAoIBAQCMVKOR+SYzneBm\n" + 
            "5hmUa2CxW5sVb7qHj54iiwLj4EYY2EnIaljjol+eh56Qrb2fpWiV3FZnQdspn/md\n" + 
            "i7W3JBngYABjwmN0/20UVL3cErVZN/XqgiFtKp2gfhfgI3BgPI/YYIWyVKRNJGt/z6Rf6\n" + 
            "0+zImQLMbUGNHkHlxuSjas+CL93sYrXo52TXqZgkfghgf40gEkQVLE+SLrtXTFiOOlX/s\n" + 
            "WWXyeUY14hl+oVQLmEO6UZd532bxAE0VlIV6Vr2pE3gJqEyaAoGgkT3inxvRPiek\n" + 
            "swRm9OONWZD9frKXYqabJTsd87623Czg5h2WGimsN4fZ+LfyBXul24KKVeMDELHn\n" + 
            "GvdRm95lAoGBAPMQRrb3iB8oYJc+4KwbtWR/vTQW++G69CeyIfD7WM0Ix3Gy0wod\n" + 
            "FwIeKSkYsZ/R5n+9Ucx/RVFv7X86YzYajhH3hl+8/q4c+L1yAGS5hW3m21gIViDt\n" + 
            "k1h3gKLI5o4EKGhCRX1teSoZ+n4G7KlYbJas8h5MX3u81GhKRmiVItr/AoGBANJg\n" + 
            "KoIhxKsyNRccULosYZBGc3vpkFtpHeZ5w0qxbXaGveUIKvqzUqonGy0o3yqVNRrH\n" + 
            "JJREHss+5/HqeuauawKUYLWapCqmVF6IlDc1PxTw+BLDzgzMlX2o43951iTMJXkd\n" + 
            "80MOujsnyTdZq7wAzR7KNR3U/OjDFlcORxhCGrnLAoGBAONZcgtp9NTP+6j8k0Ho\n" + 
            "mP5rzRmP9gHp0L3gjIbPUvxVHdhnn6ZyFzdP5sgd5ObMeoE5H+3bjYbi3o6Gmo3c\n" + 
            "wM5lbDbYnI9XYgIxQ9TzAq8NpFTvV0Btd8jj3lpk9+IWWYVLl5v+bbrHmdmPuIWd\n" + 
            "w9Qb6EwWu6kNss/pyXnBJV0ZAoGAPj+2VEsppn50tyHpwSzgsZAnG8NAs8umzUu6\n" + 
            "PZ/ChA/aoKqKDSSCkVaA9Bvj7PW5gPLsH/MIKZuzhiGbvCZgA6Nj+liHuxb8X/yJ\n" + 
            "3swink+vF95YWfEvSr9ukYm7k6fUbsIt+OmisV5Ua8xcxIR4LWQn02vyae1P7vKK\n" + 
            "luL4hYECgYEAmSiiHa4bSLF8MT/IbL2YIrxK4yatABvVWZLkAV7hiFJWeEhLCmCd\n" + 
            "OKcX8QSq9lT6TbS6NCEfHfCR0FFrny4nZMT3YnyDkgrYOiHhZL/YVfr3Izr62Gcy\n" + 
            "PizNJH/JWoNDonAuFi+eQjgBRNfd894pMeCT4tMu2nE1SOEafzykzPA=\n" + 
            "-----END RSA PRIVATE KEY-----";

    static final String DIGEST_ALGO = "SHA-1";
    static final String ENCRYPTION_ALGO = "RSA/ECB/PKCS1Padding";
    static String applicationId = "dummyApplicationId";
    static String perfiosTransactionId = "PLEASE UPDATE ME";
    static String format = "xml";

public static String payloadStatement = "<payload>\n"
            + "<vendorId>"
            + vendor
            + "</vendorId>\n"
            + "<txnId>"
            + applicationId
            + "</txnId>\n"
            + "<yearMonthFrom>2015-06</yearMonthFrom>\n" + 
            "<yearMonthTo>2016-02</yearMonthTo>"
            + "<emailId>#email#</emailId>\n<destination>statement</destination>\n"
            + "<returnUrl>" + returnURL + "</returnUrl>\n" + "</payload>";









    public static void main(String[] args) throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        if (args.length > 1 && args[0] != null) {
            if ("encrypt".equals(args[0])) {
                if (args[1] != null) {
                    String encrypt = encrypt(args[1], ENCRYPTION_ALGO,
                            buildPublicKey(privateKey));
                    System.out.print(encrypt);
                } else {
                    throw new Exception("Wrong number of arguments provided.");
                }
            } else if ("signature".equals(args[0])) {
                if (args[1] != null) {
                    String signature = getSignature(ENCRYPTION_ALGO,
                            DIGEST_ALGO, buildPrivateKey(privateKey), args[1]);
                    System.out.print(signature);
                } else {
                    throw new Exception("Wrong number of arguments provided.");
                }
            }
        } else {
            String argPerfiosTxnId = System.getProperty("perfiosTransactionId");
            if (argPerfiosTxnId != null)
                perfiosTransactionId = argPerfiosTxnId;

            String argTxnId = System.getProperty("applicationId");
            if (argTxnId != null)
                applicationId = argTxnId;

            System.out
                    .println("This program helps you try out Perfios APIs to initiate and track Perfios online transactions. "
                            + "\nIt generates HTML files that can be opened in a browser to initiate or track the transaction.");

            /** Create a folder for customer */
            File folder = new File(vendor);
            String message = "\n\nnetbanking and statement APIs are the APIs to start the transaction. \n"
                    + "Only integration supported to start the transaction is through autopost form as in the netbanking and statement htmls.\n"
                    + "All other APIs are xml over HTTP and do not need browser to be present.\n"
                    + "You can directly invoke those APIs using other mechanisms.\n\n"
                    + "Trying this program:\n"
                    + "\t(1)First run the program and it will generate the netbanking and statement upload files.\n"
                    + "\t(2)Depending upon whether you have requested these features to be available, you should be able to start the transactions.\n"
                    + "\t(3)netbanking and statment HTML start the perfios transaction using browser to browser integration.\n"
                    + "\t\t(3.1)To start netbanking transaction, open netbanking_* file in your browser..\n"
                    + "\t\t(3.2)To start statement upload transaction, open statement_* file in your browser..\n"
                    + "\t(4)You can then check the status of all transactions using txnstatus API.\n"
                    + "\t\t(4.1)To check the status of transaction, open txnstatus_* file in your browser. \n"
                    + "\t\t\tThis API could also be accessed without a browser. Without autoform load request\n"
                    + "\t(5)To retrieve a report, you will need to re-run the program. Change the value of perfiosTransactionId variable in your program.\n"
                    + "\t\t Compile and run the java program. open retrieve_* file in your browser. This API could also be accessed without a browser.\n"
                    + "\t\t Without autoform load request\n"
                    + "\t(5)To delete the transaction related artifacts, you will need to re-run the program. \n"
                    + "\t\tChange the value of perfiosTransactionId variable in your program. Compile and run the java program. open delete_* \n"
                    + "\t\tfile in your browser. This API could also be accessed without a browser. Without autoform load request\n"
                    + "You can pass applicationId and perfiosTransactionId through command line by providing system properties too. "
                    + "For e.g. java -DperfiosTransactionId=HDJDJ com.perfios.sample.OnlineSampleCapitalInfusionIndia\n"
                    + "\t(6)For more details please refer the API guide.\n";

            System.out.println(message);

            if (!folder.exists())
                folder.mkdir();

            System.out
                    .println("Your files will be created in the following location: "
                            + folder.getAbsolutePath());

            /** Create files for the customer */
            String  myHTML = genericCreateHTML(JavaApplication1.payloadStatement);
            createFile("statement", myHTML);








        }
    }

    private static void createFile(String classification, String myHTML) {
        String filename = vendor + "/" + classification + "_" + server
                + ".html";

        try {
            PrintWriter out = new PrintWriter(filename);
            out.print(myHTML);
            out.close();
            System.out.println("Successfully created file " + filename);
        } catch (Exception e) {
            System.out.println("Error while creating file " + filename);
            e.printStackTrace();
        }
    }

    private static String genericCreateHTML(String payload) {
        return genericCreateHTML(payload, null);
    }

    private static String genericCreateHTML(String payload, String operation) {

        String emailEncrypted = encrypt(email, ENCRYPTION_ALGO,
                buildPublicKey(privateKey));
        payload = payload.replaceAll("\n", "");
        payload = payload.replaceAll("#email#", emailEncrypted);

        String signature = getSignature(ENCRYPTION_ALGO, DIGEST_ALGO,
                buildPrivateKey(privateKey), payload);
        if (operation == null)
            operation = "start";
        String myHTML = "<html>\n"
                + " <body onload='document.autoform.submit();'>\n"
                + "     <form name='autoform' method='post' action='https://"
                + server + "/KuberaVault/insights/" + operation + "'>\n"
                + "         <input type='hidden' name='payload' value='" + payload
                + "'>\n" + "            <input type='hidden' name='signature' value='"
                + signature + "'>\n" + "        </form>\n" + "  </body>\n"
                + "</html>\n";
        return myHTML;
    }

    public static String getSignature(String encryptAlgo, String digestAlgo,
            Key k, String xml) {
        String dig = makeDigest(xml, digestAlgo);
        return encrypt(dig, encryptAlgo, k);
    }

    private static PrivateKey buildPrivateKey(String privateKeySerialized) {
        StringReader reader = new StringReader(privateKeySerialized);
        PrivateKey pKey = null;
        try {
            PEMReader pemReader = new PEMReader(reader);
            KeyPair keyPair = (KeyPair) pemReader.readObject();
            pKey = keyPair.getPrivate();
            pemReader.close();
        } catch (IOException i) {
            i.printStackTrace();
        }
        return pKey;
    }

    private static PublicKey buildPublicKey(String privateKeySerialized) {
        StringReader reader = new StringReader(privateKeySerialized);
        PublicKey pKey = null;
        try {
            PEMReader pemReader = new PEMReader(reader);
            KeyPair keyPair = (KeyPair) pemReader.readObject();
            pKey = keyPair.getPublic();
            pemReader.close();
        } catch (IOException i) {
            i.printStackTrace();
        }
        return pKey;
    }

    public static String makeDigest(String payload, String digestAlgo) {
        String strDigest = "";
        try {
            MessageDigest md = MessageDigest.getInstance(digestAlgo);
            md.update(payload.getBytes("UTF-8"));
            byte[] digest = md.digest();
            byte[] encoded = Hex.encode(digest);
            strDigest = new String(encoded);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return strDigest;
    }

    public static String encrypt(String raw, String encryptAlgo, Key k) {



        String strEncrypted = "";
        try {
            Cipher cipher = Cipher.getInstance(encryptAlgo);
            cipher.init(Cipher.ENCRYPT_MODE, k);
            byte[] encrypted = cipher.doFinal(raw.getBytes("UTF-8"));
            byte[] encoded = Hex.encode(encrypted);
            strEncrypted = new String(encoded);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return strEncrypted;
    }

}

我的观点是,我生成了签名和有效负载,但我不知道我的脚本出了什么问题。任何人都可以指导我吗?

php encryption rsa signature private-key
1个回答
1
投票

它试图解决代码中的一些可能问题。也许尝试这样的基础。

<?php

$email = "[email protected]";
$server = "demo.perfios.com";
$vendor = "finmomenta";
$returnURL = "https://www.google.com";
$applicationId = "dummyApplicationId";
$perfiosTransactionId = "PLEASE UPDATE ME";
$format = "xml";

$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
    "MIIEpQIBAAKCAQEAx76oeNWYPkAbbSPyvJcPkQvAMvIHCPgY9yNdN/qsYMHytyit\n" .
    "xdO0aTatgfS/ig4zmqKFVpC9o2YMyQ7E1FYNcl/ev++r4nV+qVXA1OKcsSv4Kbj/\n" .
    "iNwxGmnhBsRDswY/dEZZDN9RisRpo9NRSOskGRv+nLEA2dLgj0/f9SSzykz3cxAP\n" .
    "bq6bV0unie5C8r6RALj+hTLU7B7QF88SkDsFx0/TYQe4H9QJtFMWJtOnhumY5Ku6\n" .
    "CL4OdZrtz71y4ji8IxQxv2nyq0JwYQ4rG84uzJQeRQf2RaJLhnSdfQnonDkP7L1z\n" .
    "NSizzi8VgHI+GVIo9FrLj7DVo+fFzMucbsvvNQIDAQABAoIBAQCMVKOR+SYzneBm\n" .
    "5hmUa2CxW5sVb7qHj54iiwLj4EYY2EnIaljjol+eh56Qrb2fpWiV3FZnQdspn/md\n" .
    "i7W3JBngYABjwmN0/20UVL3cErVZN/XqgiFtKp2I3BgPI/YYIWyVKRNJGt/z6Rf6\n" .
    "0+zImQLMbUGNHkHlxuSjas+CL93sYrXo52TXqZgk40gEkQVLE+SLrtXTFiOOlX/s\n" .
    "WWXyeUY14hl+oVQLmEO6UZd532bxAE0VlIV6Vr2pE3gJqEyaAoGgkT3inxvRPiek\n" .
    "swRm9OONWZD9frKXYqabJTsd87623Czg5h2WGimsN4fZ+LfyBXul24KKVeMDELHn\n" .
    "GvdRm95lAoGBAPMQRrb3iB8oYJc+4KwbtWR/vTQW++G69CeyIfD7WM0Ix3Gy0wod\n" .
    "FwIeKSkYsZ/R5n+9Ucx/RVFv7X86YzYajhH3hl+8/q4c+L1yAGS5hW3m21gIViDt\n" .
    "k1h3gKLI5o4EKGhCRX1teSoZ+n4G7KlYbJas8h5MX3u81GhKRmiVItr/AoGBANJg\n" .
    "KoIhxKsyNRccULosYZBGc3vpkFtpHeZ5w0qxbXaGveUIKvqzUqonGy0o3yqVNRrH\n" .
    "JJREHss+5/HqeuauawKUYLWapCqmVF6IlDc1PxTw+BLDzgzMlX2o43951iTMJXkd\n" .
    "80MOujsnyTdZq7wAzR7KNR3U/OjDFlcORxhCGrnLAoGBAONZcgtp9NTP+6j8k0Ho\n" .
    "mP5rzRmP9gHp0L3gjIbPUvxVHdhnn6ZyFzdP5sgd5ObMeoE5H+3bjYbi3o6Gmo3c\n" .
    "wM5lbDbYnI9XYgIxQ9TzAq8NpFTvV0Btd8jj3lpk9+IWWYVLl5v+bbrHmdmPuIWd\n" .
    "w9Qb6EwWu6kNss/pyXnBJV0ZAoGAPj+2VEsppn50tyHpwSzgsZAnG8NAs8umzUu6\n" .
    "PZ/ChA/aoKqKDSSCkVaA9Bvj7PW5gPLsH/MIKZuzhiGbvCZgA6Nj+liHuxb8X/yJ\n" .
    "3swink+vF95YWfEvSr9ukYm7k6fUbsIt+OmisV5Ua8xcxIR4LWQn02vyae1P7vKK\n" .
    "luL4hYECgYEAmSiiHa4bSLF8MT/IbL2YIrxK4yatABvVWZLkAV7hiFJWeEhLCmCd\n" .
    "OKcX8QSq9lT6TbS6NCEfHfCR0FFrny4nZMT3YnyDkgrYOiHhZL/YVfr3Izr62Gcy\n" .
    "PizNJH/JWoNDonAuFi+eQjgBRNfd894pMeCT4tMu2nE1SOEafzykzPA=\n" .
    "-----END RSA PRIVATE KEY-----";


$payloadStatement = "<payload>\n" .
    "<vendorId>" . $vendor . "</vendorId>\n" .
    "<txnId>" . $applicationId . "</txnId>\n" .
    "<yearMonthFrom>2017-06</yearMonthFrom>\n" .
    "<yearMonthTo>2017-12</yearMonthTo>" .
    "<emailId>#email#</emailId>\n<destination>statement</destination>\n" .
    "<returnUrl>" . $returnURL . "</returnUrl>\n" .
    "</payload>";


echo genericCreateHTML($payloadStatement, 'start', $email, $server, $privateKey);

function genericCreateHTML($payload, $operation, $email, $server, $privateKey)
{
    $email = encryptData($email, $privateKey);
    $payload = str_replace("#email#", $email, $payload);

    // Remove all line breaks
    $payload = str_replace("\n", "", $payload);

    $signature = getSignature($payload, $privateKey);

    $html = "<html>\n" . " <body onload='document.autoform.submit();'>\n" .
        "     <form name='autoform' method='post' action='https://" . $server . "/KuberaVault/insights/" . $operation . "'>\n" .
        "         <input type='hidden' name='payload' value='" . $payload . "'>\n" .
        "            <input type='hidden' name='signature' value='" . $signature . "'>\n" .
        "        </form>\n" . "  </body>\n" .
        "</html>\n";

    return $html;
}

function getSignature($data, $privateKey)
{
    // Make digest
    $digest = sha1($data);

    // Encrypt
    return encryptData($digest, $privateKey);
}

function encryptData($raw, $privateKey)
{
    $privateKey = openssl_pkey_get_private($privateKey);

    if (!$privateKey) {
        throw new RuntimeException('Invalid private key or passphrase');
    }

    // Encrypt digest using the key
    $encrypted = "";
    openssl_private_encrypt($raw, $encrypted, $privateKey, OPENSSL_PKCS1_PADDING);

    // Convert to Hex (base16)
    $result = bin2hex($encrypted);

    return $result;
}
© www.soinside.com 2019 - 2024. All rights reserved.