Open anokmik opened 6 years ago
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.
Hello,
Please, update HpsTokenService to support SSL pinning. Updated implementation is provided below.
Thanks!
Best regards, Mikle Anokhin.