шифрование — Как зашифровать данные с помощью закрытого ключа RSA в php?

В настоящее время я работаю в финансовом приложении, использующем php. Так что я интегрирован со сторонним API для извлечения пользовательских данных.

На основе интеграции они проходят аутентификацию с подписью и полезной нагрузкой.

Согласно документу, я все сделал правильно с моей точки зрения, но я получил ответ как

SignatureDoesNotMatch

Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи.

Согласно документу:

Расчет подписи:
Запросы, при необходимости, должны быть подписаны отправителем. Подпись запроса рассчитывается следующим образом:

  1. Сократите полезные данные XML в одну строку следующим образом:
    2. Удалите декларацию XML
    3. Удалить все комментарии
    4. Удалить все разрывы строк
    5. Нормализация пространства

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

поэтому здесь генерируется полезная нагрузка и подпись и отправляется URL с методом post:

<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;
}

}

С моей точки зрения, я создал подпись и полезную нагрузку, но я не знаю, где не так с моим сценарием. Кто-нибудь может мне помочь?

0

Решение

Он пытался исправить некоторые возможные проблемы в вашем коде. Может быть, попробовать что-то подобное в качестве основы.

<?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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]