Friday, May 26, 2017

Stripe Payment API: Create Token Using Credit Card Details

What is need at first is to you have need an Stripe account. If you haven't that yet follow the link https://dashboard.stripe.com/register to create one. After that you need to collect API Key from Stripe portal. Below is a screenshot attached to describe how API Key collected.



Next step is to collect credit card details from end user and sent them to stripe to create a token to use further. Below is a full PHP Script that create and retrieve token from Stripe end.

Below are list of test credit cards for Stripe:
https://stripe.com/docs/testing



<?php
$params = array(
    "card" => array(
        "name" => "Card Name",
        "number" => "4242424242424242",
        "exp_month" => "12",
        "exp_year" =>  "19",
        "cvc" => "123"
    )
);

$create = CreateToken::create($params);
CreateToken::prettyPrint($create);

if ($create["code"] == 200) {
    $get = CreateToken::get($create["response"]->id);
    CreateToken::prettyPrint($get);
}

class CreateToken {
    private static $key = "sk_test_...................";

    static function create($params)
    {
        $url = "https://api.stripe.com/v1/tokens";

        $headers[] = "Authorization: Bearer " . self::$key;
        $headers[] = "Content-Type: application/x-www-form-urlencoded";

        return makeCurlCall($url, "POST", null, $params, $headers);
    }

    static function get($id)
    {
        $url = "https://api.stripe.com/v1/tokens/$id";

        $headers[] = "Authorization: Bearer " . self::$key;
        $headers[] = "Content-Type: application/x-www-form-urlencoded";

        return makeCurlCall($url, "GET", null, null, $headers);
    }

    static function prettyPrint($data)
    {
        echo "<pre>";
        print_r($data);
        echo "</pre>";
    }
}


Below is output for error response:
Array
(
    [code] => 402
    [response] => stdClass Object
        (
            [error] => stdClass Object
                (
                    [message] => Your card number is incorrect.
                    [type] => card_error
                    [param] => number
                    [code] => incorrect_number
                )
        )
)

Below is output for success response:

Array
(
    [code] => 200
    [response] => stdClass Object
        (
            [id] => tok_1ANblQFIwfarG3vBaSA6dNaX
            [object] => token
            [card] => stdClass Object
                (
                    [id] => card_1ANblQFIwfarG3vBdjdo6nd5
                    [object] => card
                    [address_city] =>
                    [address_country] =>
                    [address_line1] =>
                    [address_line1_check] =>
                    [address_line2] =>
                    [address_state] =>
                    [address_zip] =>
                    [address_zip_check] =>
                    [brand] => Visa
                    [country] => US
                    [cvc_check] => unchecked
                    [dynamic_last4] =>
                    [exp_month] => 12
                    [exp_year] => 2019
                    [fingerprint] => SmsX0otFJxkdwdrG
                    [funding] => credit
                    [last4] => 4242
                    [metadata] => stdClass Object
                        (
                        )
                    [name] => Card Name
                    [tokenization_method] =>
                )
            [client_ip] => 103.59.179.132
            [created] => 1495779452
            [livemode] =>
            [type] => card
            [used] =>
        )
)

Thursday, May 25, 2017

PHP Script - detect whether running under Linux or Windows?

PHP script - detect whether running under Linux or Windows or other Operating System? I don't have so much knowledge but can overcome with some solution. "PHP_OS" will solve this issue. Below is function to check if OS is Windows or not:

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    echo 'Windows!';
} else {
    echo 'Other Than Windows!';
}

PHP_OS will output below list of Operating System, not full list but I think it's almost all.
  • CYGWIN_NT-5.1
  • Darwin
  • FreeBSD
  • HP-UX
  • IRIX64
  • Linux
  • NetBSD
  • OpenBSD
  • SunOS
  • Unix
  • WIN32
  • WINNT
  • Windows
You can see on Wikipedia for more information.


Wednesday, May 24, 2017

PHP Encrypt Data With OpenSSL Public Key And Decrypt With OpenSSL Private Key

Below is a PHP code snippet to encrypt data with a public key and then again decrypt the encrypted data with a private key.
 

If you have fetched the problem "error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size" then use the below code snippet to overcome this problem.
 

It's a good solution to handle big size data, but don't try too big size data with this method actually when you post file.
Raw data is fine.  




$data = "Large data to test. Large data to test. Large data to test. Large data to test.";
$data = $data . $data . $data . $data . $data . $data . $data . $data;
$data = $data . $data . $data . $data . $data . $data . $data . $data;
encryptAndDecrypt($data);

function encryptAndDecrypt($data)
{
    echo "Original data length=" . strlen($data) . "<BR>";

    $private_key = openssl_pkey_get_private(readServerFile("./XeroCerts/privatekey.pem"));
    $public_key = openssl_pkey_get_public(readServerFile("./XeroCerts/publickey.cer"));

    //Block size for encryption block cipher for 1024 bit key
    $encrypt_size = 110;

    //Block size for decryption block cipher for 1024 bit key
    $decrypt_size = 128;

    //For encryption we would use:
    $encrypted = '';
    $data = str_split($data, $encrypt_size);
    foreach ($data as $chunk) {
        openssl_public_encrypt($chunk, $partial, $public_key, OPENSSL_PKCS1_PADDING);
        $encrypted .= $partial;
    }
    openssl_free_key($public_key);
    $encrypted = base64_encode($encrypted);
    echo "Encrypted=" . $encrypted . "<BR>";

    //For decryption we would use:
    $decrypted = '';
    $data = str_split(base64_decode($encrypted), $decrypt_size);
    foreach ($data as $chunk) {
        openssl_private_decrypt($chunk, $partial, $private_key, OPENSSL_PKCS1_PADDING);
        $decrypted .= $partial;
    }
    openssl_free_key($private_key);
    echo "Decrypted=" . $decrypted;
    die();
}

Output of the above code snippet is below: 


If you don't want to save strings in clear text, there are new php functions (php >= 5.3.0) that can be of help; openssl_encrypt() and openssl_decrypt().

Original data length=5056
Encrypted=Vf2GHkx..............LgpFjM9gY/FkIYWaELHl3I=
Decrypted=Large data to test. ............ Large data to test. Large data to test. Large data to test.

Simple PHP encrypt and decrypt Using AES-256-CBC Algorithm | OpenSSL Encrypt | OpenSSL Decrypt

If you don't want to save strings in clear text, there are new php functions (php >= 5.3.0) that can be of help; openssl_encrypt() and openssl_decrypt(). 


<?php
define("SSL_SECRET_KEY", "SSL_SECRET_KEY");
define("SSL_SECRET_IV", "SSL_SECRET_IV");
define("SSL_ENCRYPTION_METHOD", "AES-256-CBC");
define("SSL_SECRET_IV_SIZE", openssl_cipher_iv_length(SSL_ENCRYPTION_METHOD));

function encryptData($string)
{
    $key = hash('sha256', SSL_SECRET_KEY);
    /* If you want random IV */
    //$iv = openssl_random_pseudo_bytes(SSL_SECRET_IV_SIZE);
    $iv = substr(hash('sha256', SSL_SECRET_IV), 0, SSL_SECRET_IV_SIZE);

    $output = openssl_encrypt($string, SSL_ENCRYPTION_METHOD, $key, 0, $iv);
    return base64_encode($output);
}

function decryptData($string)
{
    $key = hash('sha256', SSL_SECRET_KEY);
    $iv = substr(hash('sha256', SSL_SECRET_IV), 0, SSL_SECRET_IV_SIZE);

    return openssl_decrypt(base64_decode($string), SSL_ENCRYPTION_METHOD, $key, 0, $iv);
}

$REQUEST_URI = isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : "";

if (strpos($REQUEST_URI, "enc.php") !== false) {
    $plain_txt = "Value to be encrypt & decrypt";
    echo "Original Text = $plain_txt<br/>";

    $encrypted_txt = encryptData($plain_txt);
    echo "Encrypted Text = $encrypted_txt<br/>";

    $decrypted_txt = decryptData($encrypted_txt);
    echo "Decrypted Text = $decrypted_txt<br/>";

    if ($plain_txt === $decrypted_txt) echo "SUCCESS";
    else echo "FAILED";

    echo "<br/>";
}


Original Text:
Value to be encrypt & decrypt

Encrypted Text = 
RjFhMElpR0VzMVlPeVdtREVraFJzYnhnNXZ4ck4vSmhRVUtXWXJoUzBVWT0=

Decrypted Text
Value to be encrypt & decrypt

SUCCESS 

Or (This will carry IV with encrypted text itself):

<?php
define("SSL_SECRET_KEY", "xorxorxorxorxor");
define("SSL_ENCRYPTION_METHOD", "AES-256-CBC");
define("SSL_SECRET_IV_SIZE", openssl_cipher_iv_length(SSL_ENCRYPTION_METHOD));

function encryptData($string)
{
    $key = hash('sha256', SSL_SECRET_KEY);
    $iv = openssl_random_pseudo_bytes(SSL_SECRET_IV_SIZE);

    $output = openssl_encrypt($string, SSL_ENCRYPTION_METHOD, $key, 0, $iv);
    return base64_encode($iv . ":" . $output);
}

function decryptData($string)
{
    $string = explode(":", base64_decode($string));
    $key = hash('sha256', SSL_SECRET_KEY);

    return openssl_decrypt($string[1], SSL_ENCRYPTION_METHOD, $key, 0, $string[0]);
}

$plain_txt = "Value to be encrypt & decrypt";
echo "Original Text = $plain_txt<br/>";

$encrypted_txt = encryptData($plain_txt);
echo "Encrypted Text = $encrypted_txt<br/>";

$decrypted_txt = decryptData($encrypted_txt);
echo "Decrypted Text = $decrypted_txt<br/>";

if ($plain_txt === $decrypted_txt) echo "SUCCESS";
else echo "FAILED";

echo "<br/>";

Original Text:

Value to be encrypt & decrypt

Encrypted Text:
NfDWpobv5RGaC29EpXvP7Dp2WkJjN2pETmdPendsZkdsMnBVQXBTK2pRekJTNkhlTndEdTRGd3h6eHpFPQ==

Decrypted Text:
Value to be encrypt & decrypt

SUCCESS

Get last word from URL after a slash in PHP (www.xxx.com/about.php/THIS_WORD)

This summary is not available. Please click here to view the post.

PHP - Sign Request Data With OpenSSL Private Key Pair

Below is a PHP code snippet to sign request data with OpenSSL private key. It's used to handshake with server to communicate with the server.

function signRequestParams($options)
{
    $private_key = openssl_pkey_get_private(readServerFile("./XeroCerts/privatekey.pem"));
    $sbs = escapeUrlEntity(normalizeParameters($options));
    openssl_sign($sbs, $signature, $private_key);
    openssl_free_key($private_key);
    return base64_encode($signature);
}

function readServerFile($file_path)
{
    $fp = fopen($file_path, "r");
    $file_contents = fread($fp, 8192);
    fclose($fp);
    return $file_contents;
}

function normalizeParameters($parameters)
{
    $elements = array();
    ksort($parameters);
    foreach ($parameters as $paramName => $paramValue) {
        /* If name contains "be_ignored" will be ignored */
        if (preg_match('/be_ignored/', $paramName))
            continue;
        if (is_array($paramValue)) {
            sort($paramValue);
            foreach ($paramValue as $element)
                array_push($elements, escapeUrlEntity($paramName) . '=' . escapeUrlEntity($element));
            continue;
        }
        array_push($elements, escapeUrlEntity($paramName) . '=' . escapeUrlEntity($paramValue));
    }
    return join('&', $elements);
}

function escapeUrlEntity($string)
{
    if ($string === 0)
        return 0;
    if (empty($string))
        return '';
    if (is_array($string))
        throw new Exception('Array passed to escapeUrlEntity');

    $string = rawurlencode($string);
    $string = str_replace('+', '%20', $string);
    $string = str_replace('!', '%21', $string);
    $string = str_replace('*', '%2A', $string);
    $string = str_replace('\'', '%27', $string);
    $string = str_replace('(', '%28', $string);
    $string = str_replace(')', '%29', $string);
    return $string;
}

$options = array(
    "card.PAN" => "4564710000000004",
    "card.CVN" => "847",
    "card.expiryMonth" => "12",
    "card.expiryYear" => "20"
);

$signature = signRequestParams($options);
echo "Signature=$signature";

Output will be as below:

Signature=UC/uRPTaNxMV02a9I/KlWL/BA8..............6Fx1hjEYHWXN0U=

How to sign string as well sign request body with public key using Java

Below is a code snippet which will sign your request using Public key.


package com.pkm.src;

import Base64OutputStream;
import IOUtil;

import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * Created by pritom on 24/05/2017.
 */
public class SignatureSigner {
    public static void main(String[] args) throws Exception {
        String certificateFile = ".....\\publickey.cer";
        String requestBody = "Param1=Value_Of_Param1&Param2=Value_Of_param2";
        String signature = encodeRSASHA1(certificateFile, requestBody);
        System.out.println("Signature=" + signature);
    }

    protected static String encodeRSASHA1(String certificateFile, String requestBody) throws Exception {
        FileInputStream certIn1 = new FileInputStream(certificateFile);
        CertificateFactory e = CertificateFactory.getInstance("X509");
        X509Certificate myCertificate = (X509Certificate) e.generateCertificate(certIn1);

        MessageDigest hashGen = MessageDigest.getInstance("SHA1");
        byte[] hash = hashGen.digest(requestBody.getBytes("UTF-8"));
        Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        rsa.init(1, myCertificate);
        byte[] signature = rsa.doFinal(hash);

        ByteArrayInputStream sigIn = new ByteArrayInputStream(signature);
        ByteArrayOutputStream sigOut = new ByteArrayOutputStream();
        Base64OutputStream base64Out = new Base64OutputStream(sigOut, "");
        IOUtil.copy(sigIn, base64Out);
        base64Out.close();
        return new String(sigOut.toByteArray(), "US-ASCII");
    }
}

Which will output as below:

Signature=7GNccit4cY+rs4t/S0WBv.........+w1rYdiEO8PxuR3SQ=