2017-12-16 79 views
0

現在、phpを使用して金融ベースのアプリケーションで作業しています。ユーザーデータを取得するためにサードパーティのAPIと統合されています。PHPでRSA秘密鍵でデータを暗号化するには?

インテグレーションに基づいて、署名とペイロードで認証しています。文書を1として

、私は右の私の視点のためにすべてをした、しかし、私は、我々が算出した要求の署名が指定した署名と一致しません

SignatureDoesNotMatch のような応答を得ました。文書1として

署名を計算する:、送信者によって署名されなければならない必要 要求を。次のように要求の署名が計算される。

  1. 次のように単一のラインにペイロードXMLを凝縮: 2.Remove XML宣言 3.Removeをすべてのコメント 4.Removeすべてのラインが 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); 

はそうここペイロードと署名を生成し、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; 
    } 

} 

私のポイントは、私が署名し、ペイロードを生成したが、私はどこに私を導く私のscript.Can誰と間違っている知りませんか?

+1

'sha1'の戻り値はすでに16進数(base16)でエンコードされていると思います。 – DanielO

+0

だから、私は、ペイロードのsha1変換の後に、base_16をエンコードする必要はなく、rsa秘密鍵で直接暗号化した後に何をする必要がありますか? @DanielO。 –

答えて

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

こんにちは、ありがとうthe response.Iあなたのガイダンスに従ってスクリプトを変更しましたが、まだ同じエラーがあります。 ** SignatureDoesNotMatch 私たちが計算したリクエストの署名は、あなたが提供した署名と一致しません。 ** –

+1

16進文字列は、大文字の '$ signature = strtoupper($ signature)'で記述する必要があります。残念ながら、私はさらなる文脈情報なしでは助けることができません。 APIプロバイダのサポートに問い合わせてください。 – DanielO

+0

こんにちは、Apiのサービスプロバイダは、Javaでapiを実行するためのサンプルスクリプトを提供し、私は準拠して実行し、Javaを実行して、私たちのアプリケーションでは正常ですが、PHPの依存性は –

関連する問題