This repository was archived by the owner on Feb 27, 2025. It is now read-only.
Description Hello,
Please, update HpsTokenService to support SSL pinning. Updated implementation is provided below.
Thanks!
public class HpsTokenService {
private String mPublicKey ;
private String mCertificateBase64EncodedPublicKey ;
private String mUrl ;
public HpsTokenService (String publicKey , String certificateBase64EncodedPublicKey ) {
mPublicKey = publicKey ;
mCertificateBase64EncodedPublicKey = certificateBase64EncodedPublicKey ;
if (publicKey == null ) {
throw new IllegalArgumentException ("publicKey can not be null" );
}
String [] components = mPublicKey .split ("_" );
if (components .length < 3 ) {
throw new IllegalArgumentException ("publicKey format invalid" );
}
String env = components [1 ].toLowerCase ();
if (env .equals ("prod" )) {
mUrl = "https://api2.heartlandportico.com/SecureSubmit.v1/api/token" ;
} else {
mUrl = "https://cert.api2.heartlandportico.com/Hps.Exchange.PosGateway.Hpf.v1/api/token" ;
}
}
public HpsToken getToken (HpsCreditCard card ) throws IOException {
HttpsURLConnection conn = (HttpsURLConnection ) new URL (mUrl ).openConnection ();
HpsToken result = null ;
byte [] creds = String .format ("%s:" , mPublicKey ).getBytes ();
String auth = String .format ("Basic %s" , Base64 .encodeBase64URLSafeString (creds ));
Gson gson = new Gson ();
String payload = gson .toJson (new HpsToken (card ));
byte [] bytes = payload .getBytes ();
conn .setDoOutput (true );
conn .setDoInput (true );
conn .setRequestMethod ("POST" );
conn .addRequestProperty ("Authorization" , auth );
conn .addRequestProperty ("Content-Type" , "application/json" );
conn .addRequestProperty ("Content-Length" , String .format ("%s" , bytes .length ));
conn .connect ();
if (isSslPinningSuccessful (conn )) {
DataOutputStream requestStream = new DataOutputStream (conn .getOutputStream ());
requestStream .write (bytes );
requestStream .flush ();
requestStream .close ();
try {
InputStreamReader responseStream = new InputStreamReader (conn .getInputStream ());
result = gson .fromJson (responseStream , HpsToken .class );
responseStream .close ();
} catch (IOException e ) {
if (conn .getResponseCode () == 400 ) {
InputStreamReader errorStream = new InputStreamReader (conn .getErrorStream ());
result = gson .fromJson (errorStream , HpsToken .class );
errorStream .close ();
} else {
throw new IOException (e );
}
}
}
return result ;
}
private boolean isSslPinningSuccessful (HttpsURLConnection conn ) {
try {
Certificate [] certs = conn .getServerCertificates ();
MessageDigest md = MessageDigest .getInstance ("SHA-256" );
for (Certificate cert : certs ) {
X509Certificate x509Certificate = (X509Certificate ) cert ;
byte [] encodedPublicKey = x509Certificate .getPublicKey ().getEncoded ();
byte [] encodedPublicKeySha256Bytes = md .digest (encodedPublicKey );
String encodedPublicKeyBase64String = Base64 .encodeBase64URLSafeString (encodedPublicKeySha256Bytes );
if (mCertificateBase64EncodedPublicKey .equals (encodedPublicKeyBase64String )) {
return true ;
}
}
} catch (Exception e ) {
e .printStackTrace ();
return false ;
}
return false ;
}
}
Best regards,
Mikle Anokhin.
Reactions are currently unavailable
Hello,
Please, update HpsTokenService to support SSL pinning. Updated implementation is provided below.
Thanks!
Best regards,
Mikle Anokhin.