此代码应该读取向API发送请求时所需的SSL证书。我有.BKS文件位于assets文件夹中,但它似乎在此行System.out.println上获得一个空指针(“ca =”+((X509Certificate)ca).getSubjectDN());.请帮忙。
public HttpsURLConnection setUpHttpsConnection(String urlString)
{
try
{
Log.i("status","inside method..");
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
// My CRT file that I put in the assets folder
// I got this file by following these steps:
// * Go to https://littlesvr.ca using Firefox
// * Click the padlock/More/Security/View Certificate/Details/Export
// * Saved the file as littlesvr.crt (type X.509 Certificate (PEM))
// The MainActivity.context is declared as:
// public static Context context;
// And initialized in MainActivity.onCreate() as:
context = PayMerchant.this;
InputStream caInput = new BufferedInputStream(context.getAssets().open("core_tec.jks"));
// InputStream caInput = new BufferedInputStream("/assets/core_tec.jks"));
Certificate ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
// Log.i("ca", String.valueOf((X509Certificate) ca).getSubjectDN());
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL(urlString);
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
return urlConnection;
}
catch (Exception ex)
{
Log.e("error", "Failed to establish SSL connection to server: " + ex.toString());
return null;
}
}
这是我在运行上述代码后得到的错误。
02-17 13:19:33.825 22730-23362/com.eva.mvisa I/status: calling method..
02-17 13:19:33.825 22730-23362/com.eva.mvisa I/status: inside method..
02-17 13:19:33.835 22730-23362/com.eva.mvisa E/error: Failed to establish SSL connection to server: java.lang.NullPointerException: Attempt to invoke virtual method 'java.security.Principal java.security.cert.X509Certificate.getSubjectDN()' on a null object reference
02-17 13:19:33.835 22730-23362/com.eva.mvisa I/status: method called
02-17 13:19:33.845 22730-23362/com.eva.mvisa I/json: {"acquirerCountryCode":"356","acquiringBin":"408972","amount":"124.05","businessApplicationId":"MP","city":"KOLKATA","country":"IND","idCode":"CA-IDCode-77765","name":"Visa Inc. USA-Foster City","feeProgramIndicator":"123","localTransactionDateTime":"2017-02-13T08:12:26","referenceNumber":"REF_123456789123456789123","type":"1","recipientName":"Jasper","recipientPrimaryAccountNumber":"4123640062698790","retrievalReferenceNumber":"412770451035","secondaryId":"123TEST","senderAccountNumber":"4027290077881580","senderName":"Jasper","senderReference":" ","systemsTraceAuditNumber":"451035","transactionCurrencyCode":"INR","transactionIdentifier":"381228649430015"}
02-17 13:19:34.716 22730-23362/com.eva.mvisa I/connection: connecting...
02-17 13:19:34.716 22730-23362/com.eva.mvisa I/connection: connected
02-17 13:19:35.917 22730-23362/com.eva.mvisa I/resnotok: resnotok
02-17 13:19:35.917 22730-23362/com.eva.mvisa I/res: 403
02-17 13:19:35.917 22730-23362/com.eva.mvisa I/res: Forbidden
02-17 13:19:36.098 22730-22730/com.eva.mvisa I/InputMethodManager: [startInputInner] EditorInfo { packageName=com.eva.mvisa, inputType=0x20001, imeOptions=0x48000005, privateImeOptions=null }, windowGainingFocus=android.view.ViewRootImpl$W@917786b, mServedView=android.support.v7.widget.AppCompatEditText{3f5685ac VFED..CL .F....ID 390,556-750,683 #7f0d00da app:id/merchantid}, mServedInputConnectionWrapper=android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper@ed1e506
正在使用的新方法。
public HttpsURLConnection setUpHttpsConnection(String urlString)
{
String HttpMessage="";
int HttpResult=0;
try
{
Log.i("status","inside method..");
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
// My CRT file that I put in the assets folder
// I got this file by following these steps:
// * Go to https://littlesvr.ca using Firefox
// * Click the padlock/More/Security/View Certificate/Details/Export
// * Saved the file as littlesvr.crt (type X.509 Certificate (PEM))
// The MainActivity.context is declared as:
// public static Context context;
// And initialized in MainActivity.onCreate() as:
context = PayMerchant.this;
/* InputStream caInput = new BufferedInputStream(context.getAssets().open("core_tec.jks"));
// InputStream caInput = new BufferedInputStream("/assets/core_tec.jks"));
Certificate ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());*/
// Log.i("ca", String.valueOf((X509Certificate) ca).getSubjectDN());
// Create a KeyStore containing our trusted CAs
//String keyStoreType = KeyStore.getDefaultType();
// KeyStore keyStore = KeyStore.getInstance(keyStoreType);
//keyStore.load(null, null);
//keyStore.setCertificateEntry("ca", ca);
Log.i("here", "here");
InputStream caInput = context.getAssets().open("coretec.bks");
KeyStore keyStore = KeyStore.getInstance("BKS");
String pass="test123";
char[] keystorePassword=pass.toCharArray();
keyStore.load(caInput, keystorePassword);
Log.i("here1", "here1");
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL(urlString);
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", "SYZK9LIO98QIQNQ27H6921fgRyt63FHIxrQP76m0hNYT6BZ7I:pB1g5XX3Hw58buPENR03ZM4Vgm7P");
/*InputStream in = new BufferedInputStream(urlConnection.getInputStream());
reader = new BufferedReader(new InputStreamReader(in));*/
JSONObject postjson = new JSONObject();
postjson.put("acquirerCountryCode","356");
postjson.put("acquiringBin","408972");
postjson.put("amount","124.05");
postjson.put("businessApplicationId","MP");
postjson.put("city","KOLKATA");
postjson.put("country","IND");
postjson.put("idCode","CA-IDCode-77765");
postjson.put("name","Visa Inc. USA-Foster City");
postjson.put("feeProgramIndicator","123");
postjson.put("localTransactionDateTime","2017-02-13T08:12:26");
postjson.put("referenceNumber","REF_123456789123456789123");
postjson.put("type","1");
postjson.put("recipientName","Jasper");
postjson.put("recipientPrimaryAccountNumber","4123640062698790");
postjson.put("retrievalReferenceNumber","412770451035");
postjson.put("secondaryId","123TEST");
postjson.put("senderAccountNumber","4027290077881580");
postjson.put("senderName","Jasper");
postjson.put("senderReference"," ");
postjson.put("systemsTraceAuditNumber","451035");
postjson.put("transactionCurrencyCode","INR");
postjson.put("transactionIdentifier","381228649430015");
Log.i("json", String.valueOf(postjson));
DataOutputStream localDataOutputStream = new DataOutputStream(urlConnection.getOutputStream());
localDataOutputStream.writeBytes(postjson.toString());
localDataOutputStream.flush();
localDataOutputStream.close();
Log.i("connection", "connecting...");
urlConnection.connect();
Log.i("connection", "connected");
HttpResult =urlConnection.getResponseCode();
HttpMessage =urlConnection.getResponseMessage();
if(HttpResult ==HttpURLConnection.HTTP_OK) {
Log.i("resok", "resok");
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
res=sb.toString();
Log.i("res", res);
} else {
Log.i("resnotok", "resnotok");
Log.i("res", String.valueOf(HttpResult));
Log.i("res", HttpMessage);
}
return urlConnection;
}
catch (Exception ex)
{
Log.e("error", "Failed to establish SSL connection to server: " + ex.toString());
return null;
}
}
答案 0 :(得分:0)
您正在尝试使用不是证书的文件core_tec.jks
加载证书。它是包含证书的密钥库。这将返回一个空值。
InputStream caInput = new BufferedInputStream(context.getAssets().open("core_tec.jks"));
Certificate ca = cf.generateCertificate(caInput);
您在问题中提到要加载BKS,因此该文件应该类似于core_tec.bks
。以这种方式加载BKS信任存储
InputStream caInput = context.getAssets().open("core_tec.bks");
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(caInput, keystorePassword);