To create the certificates(pfx for C#, jks for Java) I followed this guide
C# client:
X509Certificate cert = new X509Certificate2(certPath, "pass");
TStreamTransport socket = new TTLSSocket(host, port, cert, (o, c, chain, errors) => true, null);
var transport = new TBufferedTransport(socket);
TProtocol protocol = new TBinaryProtocol(transport);
_client = new HfmConnectorService.Client(protocol);
_client.InputProtocol.Transport.Open();
Java Server:
TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters();
File keystoreFile = new File(System.getProperty("user.dir") + "\\keystore\\hfmcon.jks");
if(!keystoreFile.exists())
throw new IOException("Keystore file missing");
params.setKeyStore(keystoreFile.getPath(), "pass");
TServerSocket serverTransport = TSSLTransportFactory.getServerSocket(port, 10000, InetAddress.getByName("localhost"), params);
The client times out on this line
_client.InputProtocol.Transport.Open();
Related
My code works, yet I have a question.
According to my code my client is proposing to the server to use TLSv1.3. Since the connection is established, I believe this is the case. However, I want to see some kind of confirmation from the server. Is this possible?
SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
SSLContext sslContext = sslUtil.createSSLContext();
String[] supportedProtocols = sslContext.getDefaultSSLParameters().getProtocols();
System.out.println("Supported Protocols = " + Arrays.toString(supportedProtocols));
String TLSversion = "TLSv1.3";
System.out.println("TLS version = " + TLSversion);
SSLSocketFactory sslSocketFactory = sslUtil.createSSLSocketFactory(TLSversion);
try
{
LDAPConnection ldc = new LDAPConnection(sslSocketFactory);
ldc.connect(this.getHost(), this.getPort());
return ldc;
}
catch (LDAPException le)
{
System.out.println(le);
};
How to setup Apache Thrift communication between a Java client and a PHP server?
I have PHP codes on server side:
$header('Content-Type', 'application/x-thrift');
$handler = new MyApplicationHandler();
$processor = new \tutorial\MyApplicationProcessor($handler);
$transport = new TFramedTransport(
new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
$protocol = new TBinaryProtocol($transport, true, true);
$transport->open();
$processor->process($protocol, $protocol);
$transport->close();
And Java codes on the client side:
THttpClient httpClient =
new THttpClient("http://my.application.com/PhpServer.php");
TTransport transport = new TFramedTransport(httpClient);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
MyApplication.Client client = new MyApplication.Client(protocol);
Boolean result = client.someApi(someData); // <-- will crash here
transport.close();
The client will crash when executing this line:
client.someApi(someData);
Is there something wrong in my codes?
I am trying to create java desktop app for online shopping. So far I am able to login, select product, and select check out
using httpsurlconnect. but after checkout site redirects to bank payment gateway. And i always get response unable to process your request after redirect.
I think this is because payment gateway uses 2-way mutual negotiation (not sure). So how can i create 2-way mutual negotiation on fourth request.
I have done a bit research on internet. i found that it requires keystore.jks and truststore.jks. I asume that JDK comes with CA truststore which can accept server certificate.
I need keystore.jks file with client key and certificate. if i create self signed cert, will the server accept it. Server users verisigned CA cert and i have no control over server.
How can i get client keystore.jks and implement handshake on fourth request. Sample code of my implementaion is given below.
public void query(){
//request 1
String url_1 = "https://www.shop.com/login.do";
String ref_1 = "https://www.shop.com/";
Map<String, String> post = new HashMap<String, String>();
post.put("userName", var.userName);
post.put("password", var.password);
String new_post_1 = Generate_post(post);
Connect(url_1, ref_1, new_post_1);
//request 2
String url_2 = "https://www.shop.com/select_product.do";
String ref_2 = "https://www.shop.com/login.do";
Map<String, String> post = new HashMap<String, String>();
post.put("product", var.Name);
post.put("id", var.id);
post.put("price", var.price);
String new_post_2 = Generate_post(post);
Connect(url_2, ref_2, new_post_2);
//request 3
String url_3 = "https://www.shop.com/checkout.do";
String ref_3 = "https://www.shop.com/select_product.do";
Map<String, String> post = new HashMap<String, String>();
post.put("product", var.Name);
post.put("id", var.id);
post.put("total_price", var.total_price);
post.put("checkout", var.checkout);
String new_post_3 = Generate_post(post);
Connect(url_3, ref_3, new_post_3);
//request 4
String url_4 = "https://secure.payment.com/gateway.do";
String ref_4 = "https://www.shop.com/checkout.do";
Map<String, String> post = new HashMap<String, String>();
post.put("total_price", var.total_price);
post.put("bank", var.bank);
post.put("confirm", var.confirm);
String new_post_4 = Generate_post(post);
Connect(url_4, ref_4, new_post_4);
}
Connnect method:
void Connect(String https_url, String referal, String query) throws IOException{
URL url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
//set properties
HttpsURLConnection.setFollowRedirects(true);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
con.setUseCaches(false);
con.setAllowUserInteraction(false);
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0");
con.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
con.setRequestProperty("Accept-Language","en-us,en;q=0.5");
con.setRequestProperty("Connection","keep-alive");
con.setRequestProperty("charset","iso-8859-1");
con.setRequestProperty("Referer",referal);
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length",String.valueOf(query.length()));
// Create Output streams
BufferedWriter outStream = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
outStream.write(query);
outStream.flush();
outStream.close();
if(con.getResponseCode()==HttpsURLConnection.HTTP_OK ){
// Create Input streams
InputStreamReader in = new InputStreamReader(con.getInputStream());
BufferedReader inStream = new BufferedReader(in, 1024*24);
String html;
StringBuffer page = new StringBuffer();
while((html = inStream.readLine()) != null) {
page.append(html+"\n"); }
inStream.close();
}else{
System.out.println(con.getHeaderFields());
InputStreamReader in = new InputStreamReader(con.getErrorStream());
BufferedReader inStream = new BufferedReader(in);
String html;
StringBuffer page = new StringBuffer();
while((html = inStream.readLine()) != null) {
page.append(html+"\n"); }
}
con.disconnect();
}
I write FTPS server, and I have problems with ssl connection after AUTH TLS command.
Simple example:
try
{
int ServerPort = 21;
ServerSocket FtpExServer = new ServerSocket(ServerPort);
while(true)
{
Socket S = FtpExServer.accept();
InputStreamReader ISR = new InputStreamReader(S.getInputStream());
OutputStreamWriter OSW = new OutputStreamWriter(S.getOutputStream());
BufferedReader ClientSocketReader = new BufferedReader(ISR);
PrintWriter ClientSocketWriter = new PrintWriter(OSW, true);
ClientSocketWriter.println("220 Welcome to FTP server.");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("234 AUTH TLS successful");
char[] passphrase = "pass".toCharArray();
char[] cpassphrase = "cpass".toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("keystore.jks"), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, cpassphrase);
SSLContext context = SSLContext.getInstance("TLS");
KeyManager[] keyManagers = kmf.getKeyManagers();
context.init(keyManagers, null, null);
SSLServerSocketFactory ssf = context.getServerSocketFactory();
SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(990);
ss.setSoTimeout(2000);
SSLSocket s = (SSLSocket)ss.accept();
ISR = new InputStreamReader(s.getInputStream());
OSW = new OutputStreamWriter(s.getOutputStream());
ClientSocketReader = new BufferedReader(ISR);
ClientSocketWriter = new PrintWriter(OSW, true);
ClientSocketWriter.println("234 AUTH TLS successful");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("331 Password required for smie");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("230 User smie logged in");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("215 UNIX Type: L8");
print(ClientSocketReader.readLine());
ClientSocketWriter.println("550 Command not suported.");
}
}
catch(Exception e)
{
print(e);
}
Description: FTP client(for example MoveITFreely) connect to server on port 21. After send command "AUTH TLS", server send "234 AUTH TLS successful". Now client must to connect to server on port 990(?), but client dont connect and get timeout exception.
What i do wrong?
There exist two methods to add SSL to FTP.
First method is called implicit SSL. It means that the server is listening on port 990 and when the client connects to it, first SSL/TLS negotiation is performed, and then the established connection is used as a command channel for communication (for data channel SSL handshake is also performed in a similar manner).
Second method is what you attempt to use. It's called explicit SSL. The client connects on port 21, sends AUTH TLS and starts SSL negotiation on existing connection. Data channel can be secured or not secured depending on how you want it (you specify this using PROT command).
You mixed the methods. I suggest that you read detailed explanation in Wikipedia before going further. Then read RFC for explicit TLS.
Update: Also you'd need SSLClientSocket, not SSLServerSocket.
i need to send a v3certificate from the server to the client using socket.
To do this:
server side, i generate a certificate which i encode with base64.encode , then i send it to the client.
Client side, i receive the string which contain the certificate,
Server code:
X509Certificate certificate = ...;
sendAnswer(new String(certificate.getEncoded()));
public static void sendAnswer(String ans) {
try {
s.shutdownInput();
PrintWriter output = new PrintWriter(s.getOutputStream(), true);
output.println(new String(Base64.encode(ans.getBytes())));
output.close();
} catch (IOException ex) {
Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
Client code
String value = sendMessage(..);//method which receive the certificate from the server
InputStream inStream = null;
X509Certificate cert=null;
inStream = new ByteArrayInputStream(value.getBytes());
CertificateFactory cf = CertificateFactory.getInstance("X.509","BC");
cert = (X509Certificate)cf.generateCertificate(inStream);
public static String sendMessage(String url, int port, String tag, byte[] mex1) {
Socket link;
String reply = "";
byte[] replyDec = null;
link = new Socket(InetAddress.getByName(url), port);
InputStream i = null;
try {
i = link.getInputStream();
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
}
Scanner input = new Scanner(i);
while (input.hasNextLine()) {
reply += input.nextLine();
}
replyDec = Base64.decode(reply);
input.close();
link.close();
return new String(replyDec);
}
Almost everything works, in the client side if i print the string i receive i get a text which contain extra character and the certificate data. But it gives me an error when creating the certificate, client side.
This is the error:
java.security.cert.CertificateException: java.io.IOException: DER length more than 4 bytes: 111
at org.bouncycastle.jce.provider.JDKX509CertificateFactory.engineGenerateCertificate(Unknown Source)
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:322)
and this is the line from which it comes from
cert = (X509Certificate) cf.generateCertificate(inStream);
Anyone can help me?
Thanks in advance
Throw it all away and use SSL, which already does all that.
You can send the certificate through socket by stream of bytes:
in sender side after configuration of socket:
ObjectOutputStream toServer;
toServer = new ObjectOutputStream(socket.getOutputStream());
byte[] frame = theCertificate.getEncoded();
toServer.writeObject(frame);
in receiver side after configuration of socket:
ObjectInputStream fromClient;
fromClient = new ObjectInputStream(socket.getInputStream());
byte[] cert = fromClient.readObject();
java.security.cert.Certificate jsCert = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(cert));
now you can use this certificate. for example as retrieving the public key:
PublicKey thepublicKey = jsCert.getPublicKey();
It looks possible that your problem might be due to using a PrintWriter to send, and possibly something different to read (scanner). You could try using a StringWriter and StringReader to have a match at either end and then also you can debug if what you send is a perfect match for what you receive.