TatraPayInformation.java
package sk.iway.iwcm.ebanking.epayments;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.ebanking.Payment;
/**
* TatraPayInformation.java
*
*@Title webjet4
*@Company Interway s.r.o. (www.interway.sk)
*@Copyright Interway s.r.o. (c) 2001-2009
*@author $Author: jraska $
*@version $Revision: 1.5 $
*@created Date: 26.8.2009 14:12:11
*@modified $Date: 2009/12/11 14:51:53 $
*/
class TatraPayInformation extends PaymentInformation
{
TatraPayInformation()
{
this.merchantId = Constants.getString("basketPaymentTatraPayMid");
this.key = getDecrypredKey(Constants.getString("basketPaymentTatraPayKey"));
this.constantSymbol = Integer.valueOf(Constants.getInt("basketPaymentTatraPayConstantSymbol"));
}
@Override
public String getUrlString()
{
String confUrl = Constants.getString("basketPaymentTatraPayUrl");
if(Tools.isNotEmpty(confUrl))
return confUrl;
else
return "https://moja.tatrabanka.sk/cgi-bin/e-commerce/start/e-commerce.jsp";
//return "http://epaymentsimulator.monogram.sk/TB_TatraPay.aspx";
}
@Override
public String getReturnEmail()
{
return Constants.getString("basketPaymentTatraPayNotificationEmail");
}
@Override
public boolean hasOwnForm()
{
return true;
}
@Override
public String generateForm(Payment payment, HttpServletRequest request)
{
if (request.getAttribute("RURL") == null)
throw new IllegalStateException("HttpServletRequest needs to have 'RURL'(return URL) attribute");
//Timestamp musí byť vo formáte DDMMYYYYHHMISS (DD-deň, MM-mesiac, YYYY-rok, HH-hodina, MI-minúta, SS-sekunda). TIMESTAMP musí byť v intrvale +/- 1 hodina voči UTC (GMT)
String timestamp = new SimpleDateFormat("ddMMYYYYHHmmss").format(new Date());
StringBuilder form = new StringBuilder().
append("<FORM action='"+getUrlString()+"' METHOD='POST' name='payForm'>").
append("<INPUT type=\"hidden\" NAME=\"MID\" value='"+getMerchantId()+"' />").
append("<INPUT type=\"hidden\" NAME=\"AMT\" value='"+payment.getAmountString()+"' />").
append("<INPUT type=\"hidden\" NAME=\"CURR\" value=\"978\" />").//978 = ISO EURO
append("<INPUT type=\"hidden\" NAME=\"VS\" value='"+payment.getVariableSymbol()+"' />").
append("<INPUT type=\"hidden\" NAME=\"CS\" value='"+payment.getConstantSymbol()+"' />").
append("<INPUT type=\"hidden\" NAME=\"RURL\" value='"+request.getAttribute("RURL")+"' />").
append("<INPUT type=\"hidden\" NAME=\"TIMESTAMP\" value='"+timestamp+"' />").
append("<INPUT type=\"hidden\" NAME=\"HMAC\" value='"+generateHMAC(getStringToSign(payment, timestamp, request))+"' />");
if (Tools.isNotEmpty(payment.getSpecificSymbol()))
form.append("<INPUT type=\"hidden\" NAME=\"SS\" value='"+payment.getSpecificSymbol()+"' />");
if (Tools.isNotEmpty(getReturnEmail()))
form.append("<INPUT type=\"hidden\" NAME=\"REM\" value='"+getReturnEmail()+"' />");
//form.append("<input type=\"submit\" value=\"Vykonať platbu\">");
form.append("</FORM>");
return form.toString();
}
private String getStringToSign(Payment payment, String timestamp, HttpServletRequest request)
{
//stringToSign = MID + AMT + CURR + VS + SS + CS + RURL + REM + TIMESTAMP;
String mid = getMerchantId();
String amt = payment.getAmountString();
String curr = "978";
String vs = payment.getVariableSymbol();
String ss = "";
if(Tools.isNotEmpty(payment.getSpecificSymbol()))
ss = payment.getSpecificSymbol();
String cs = payment.getConstantSymbol();
String rurl = request.getAttribute("RURL").toString();
String rem = "";
if(Tools.isNotEmpty(getReturnEmail()))
rem = getReturnEmail();
//System.out.println("Key tatra plain: " + paymentInfo.getKey());
//System.out.println("Key tatra hex: " + bytesToHex(paymentInfo.getKey().getBytes()));
StringBuilder stringToSign = new StringBuilder().
append(mid).
append(amt).
append(curr).
append(vs).
append(ss).
append(cs).
append(rurl).
append(rem).
append(timestamp);
return stringToSign.toString();
}
private String generateHMAC(String stringToSign)
{
String signature = null;
try
{
byte[] keyBytes = getKey().getBytes(); // konverzia do binárneho formátu
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] stringToSignBytes = stringToSign.getBytes();
byte[] hmacBin = mac.doFinal(stringToSignBytes);
signature = bytesToHex(hmacBin); // konverzia do hexadecimálneho reťazca
}
catch(NoSuchAlgorithmException e){sk.iway.iwcm.Logger.error(e);}
catch(InvalidKeyException e){sk.iway.iwcm.Logger.error(e);}
return signature;
}
String bytesToHex(byte[] bytes) {
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
@Override
public boolean validateBankResponce(HttpServletRequest request)
{
if("FAIL".equals(request.getParameter("RES")))
return false;
String stringToVerify = getStringToVerify(request);
String generatedHMAC = generateHMAC(stringToVerify);
if(generatedHMAC==null || !generatedHMAC.equals(request.getParameter("HMAC")))
return false;
return validateECDSA(request, stringToVerify);
}
private String getStringToVerify(HttpServletRequest request)
{
String amt = request.getParameter("AMT");
String curr = request.getParameter("CURR");
String vs = request.getParameter("VS");
String ss = request.getParameter("SS");
String cs = request.getParameter("CS");
String res = request.getParameter("RES");
String tid = request.getParameter("TID");
String timestamp = request.getParameter("TIMESTAMP");
if(amt==null) amt="";
if(curr==null) curr="";
if(vs==null) vs="";
if(ss==null) ss="";
if(cs==null) cs="";
if(res==null) res="";
if(tid==null) tid="";
if(timestamp==null) timestamp="";
StringBuilder stringToSign = new StringBuilder().
append(amt).
append(curr).
append(vs).
append(ss).
append(cs).
append(res).
append(tid).
append(timestamp);
return stringToSign.toString();
}
private boolean validateECDSA(HttpServletRequest request, String stringToVerify)
{
try
{
String expandedStringToVerify = stringToVerify + request.getParameter("HMAC");
String ECDSA = request.getParameter("ECDSA");
String publicKey = getECDSA(request.getParameter("ECSDA_KEY"));
if(Tools.isEmpty(publicKey))
return false;
X509EncodedKeySpec spec = new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PublicKey pKey = keyFactory.generatePublic(spec);
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initVerify(pKey);
ecdsaSign.update(expandedStringToVerify.getBytes("UTF-8"));
if (ecdsaSign.verify(new BigInteger(ECDSA, 16).toByteArray())) {
return true;
}
}
catch(Exception e) {sk.iway.iwcm.Logger.error(e);}
return false;
}
private String getECDSA(String keyId)
{
if(Tools.isEmpty(keyId))
return null;
String keysString = Tools.downloadUrl("https://moja.tatrabanka.sk/e-commerce/ecdsa_keys.txt");
if(Tools.isNotEmpty(keysString))
{
String[] keys = keysString.split("KEY_ID: ");
String result = "";
for(String key : keys)
{
if(Tools.isNotEmpty(key))
{
String[] lines = key.split("\\r?\\n");
if(lines!=null && keyId.equals(lines[0]))
{
int begin = 0;
int end = 0;
for(int i=0; i<lines.length; i++)
{
if("-----BEGIN PUBLIC KEY-----".equals(lines[i]))
begin = i+1;
if("-----END PUBLIC KEY-----".equals(lines[i]))
end = i;
}
for(int i=begin; i<end; i++)
result += lines[i];
return result;
}
}
}
}
return null;
}
}