Re: Fail to connect the VBASS using 2 way

Yong
Helper

Fail to connect the VBASS using 2 way

Hello, 

I am following this document to generate JKS store file, using KeyTool.

The commands I am using

keytool -import -alias DigiCertGlobalCA -keystore visa-integration_keyAndCertBundle.jks -file DigiCertGlobalRootCA.crt


keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -keystore visa-integration_keyAndCertBundle.jks --storepass {password} -keypass {password} -dname "CN=**, OU=**, O=**, L=**, ST=California, C=US, UID=**-PROD"


keytool -certreq -alias client -keystore visa-integration_keyAndCertBundle.jks -storepass {password} -keypass {password} -file certreq.csr

### Then I upload certreq.csr to VISA and get cert.perm and username and password.

keytool -import -alias ejbca -keystore visa-integration_keyAndCertBundle.jks -file VDPCA-SBX.pem -storepass {password}

 

keytool -import -alias client -keystore visa-integration_keyAndCertBundle.jks -file cert.pem -storepass {password}

 

Note: all the {password} above are same, I am not sure whether they are correct?  Below is my code to connect the VISA.  I got a 401 error Do you know what's wrong?

public HttpURLConnection initURLConnection(String apiUrl) {
HttpURLConnection con;

try {
URL url = new URL(apiUrl);
con = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
log.error("Fail to initialize url {}.", apiUrl);
throw new DnaJobsException(e);
} catch (IOException e) {
log.error("Fail to open connection for url {}.", apiUrl);
throw new DnaJobsException(e);
}

String keystoreFileName = getKeystoreFileName();// which is visa-integration_keyAndCertBundle.jks
String keystorePassword = getKeystorePassword();// which is password in above commands

KeyStore ks;

try {
ks = KeyStore.getInstance("PKCS12");
} catch (KeyStoreException e) {
log.error("Failed to get key store PKCS12");
throw new DnaJobsException(e);
}

ClassPathResource classPathResource = new ClassPathResource(keystoreFileName);
try (InputStream fis = classPathResource.getInputStream()) {
ks.load(fis, keystorePassword.toCharArray());
} catch (FileNotFoundException e) {
log.error("Failed to open file in {}.", keystoreFileName);
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to load keystore password");
throw new DnaJobsException(e);
}

KeyManagerFactory kmf;
try {
kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keystorePassword.toCharArray());
} catch (NoSuchAlgorithmException e) {
log.error("Failed to get key manager SunX509.");
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to initialize password");
throw new DnaJobsException(e);
}

SSLContext sslContext;

try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
} catch (NoSuchAlgorithmException e) {
log.error("Failed to get algorithm TLS.");
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to initialize password for SSLContext.");
throw new DnaJobsException(e);
}

if (con instanceof HttpsURLConnection) {
((HttpsURLConnection) con).setSSLSocketFactory(sslContext.getSocketFactory());
}

try {
con.setRequestMethod("POST");
} catch (ProtocolException e) {
log.error("Failed to set request method");
throw new DnaJobsException(e);
}

con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");

String auth = getVisaUserId() + ":" + getVisaPassword();//UserId and password are from VISA Dashboard
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
String authHeaderValue = "Basic " + new String(encodedAuth);
con.setRequestProperty("Authorization", authHeaderValue);
return con;
}

 

4 REPLIES 4
SyedSa
Community Moderator

Re: Fail to connect the VBASS using 2 way

Hi @Yong, Thank you for reaching out. An agent will get back to you as soon as possible. In the meantime, if any community member knows a solution, please reply to this thread.

Yong
Helper

Re: Fail to connect the VBASS using 2 way

Hello, do you have any feedback?

API_Products
Visa Developer Support Specialist

Re: Fail to connect the VBASS using 2 way

Hey @Yong,

 

Please refer to the Visa Developer Error Codes page for cause and resolution. 

 

Your code and commands seem mostly correct, but there are a few areas where issues might arise. Here are some suggestions:

1. Keystore Type: Your commands are for creating a JKS keystore, but in the code, you're trying to load a PKCS12 keystore. Ensure consistency between the keystore type used in your commands and your code.

2. Certificate Chain: Ensure that the certificate chain is correctly imported into the keystore.

3. HTTP Response: Check the response from the server to get more specific details about the error.

4. Password Consistency: Ensure that the password used for the keystore and keys is consistent.

5. Debugging: Enable SSL debugging for more detailed logs.

Here's an updated version of your code considering the above points:

 

```java

// START 
public HttpURLConnection initURLConnection(String apiUrl) {
HttpURLConnection con;

try {
URL url = new URL(apiUrl);
con = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
log.error("Fail to initialize url {}.", apiUrl);
throw new DnaJobsException(e);
} catch (IOException e) {
log.error("Fail to open connection for url {}.", apiUrl);
throw new DnaJobsException(e);
}

String keystoreFileName = getKeystoreFileName(); // which is visa-integration_keyAndCertBundle.jks
String keystorePassword = getKeystorePassword(); // which is password in above commands

KeyStore ks;

try {
ks = KeyStore.getInstance("JKS"); // Changed to JKS to match your keytool commands
} catch (KeyStoreException e) {
log.error("Failed to get key store JKS");
throw new DnaJobsException(e);
}

ClassPathResource classPathResource = new ClassPathResource(keystoreFileName);
try (InputStream fis = classPathResource.getInputStream()) {
ks.load(fis, keystorePassword.toCharArray());
} catch (FileNotFoundException e) {
log.error("Failed to open file in {}.", keystoreFileName);
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to load keystore password");
throw new DnaJobsException(e);
}

KeyManagerFactory kmf;
try {
kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keystorePassword.toCharArray());
} catch (NoSuchAlgorithmException e) {
log.error("Failed to get key manager SunX509.");
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to initialize password");
throw new DnaJobsException(e);
}

SSLContext sslContext;

try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
} catch (NoSuchAlgorithmException e) {
log.error("Failed to get algorithm TLS.");
throw new DnaJobsException(e);
} catch (Exception e) {
log.error("Failed to initialize password for SSLContext.");
throw new DnaJobsException(e);
}

if (con instanceof HttpsURLConnection) {
((HttpsURLConnection) con).setSSLSocketFactory(sslContext.getSocketFactory());
}

try {
con.setRequestMethod("POST");
} catch (ProtocolException e) {
log.error("Failed to set request method");
throw new DnaJobsException(e);
}

con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");

String auth = getVisaUserId() + ":" + getVisaPassword(); // UserId and password are from VISA Dashboard
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
String authHeaderValue = "Basic " + new String(encodedAuth);
con.setRequestProperty("Authorization", authHeaderValue);
return con;
}
// END 
```

Additional Tips:
1. SSL Debugging:  Add `-Djavax.net.debug=all` to your JVM options to enable detailed SSL debugging.
2. Check Server Logs: If possible, check the server logs for more information on the 401 error.
3. Certificate Chain: Ensure that the full certificate chain is correctly imported into the keystore.




Thanks,

Diana



Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.

Yong
Helper

Re: Fail to connect the VBASS using 2 way

Thank you for your reply. 
Now I found the issue in my side, while I am renewing the Prod certificate, I submitted the CSR to sandbox. Now I am resubmitting the CSR and waiting for VISA to approve it.