Apple push APNS connection - java

I am trying to connect to Apple's push notification server to send down notifications but I am having some issues connecting. After I attempt the handshake, it shows that says that I am not connected. I am not getting any exceptions? It isn't a issue with my certificate because I tried using 3rd party libraries with the certificate and I was able to push with no problem.
int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";
char[] passwKey = "password".toCharArray();
KeyStore ts = KeyStore.getInstance("PKCS12");
ts.load(new FileInputStream("/path/to/file/Cert.p12"), passwKey);
KeyManagerFactory tmf = KeyManagerFactory.getInstance("SunX509");
tmf.init(ts, passwKey);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(tmf.getKeyManagers(), null, null);
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket(hostname,port);
String[] suites = socket.getSupportedCipherSuites();
socket.setEnabledCipherSuites(suites);
//start handshake
socket.startHandshake();
//THIS ALWAYS RETURNS FALSE
boolean connected = socket.isConnected();

This always returns false, but I was able to communicate with no problems.
boolean connected = socket.isConnected();

Related

Connection reset in rabbitmq

I want to connect to rabbitmq through ssl port
Whenever I tried to connect with line
Connection conn = connectionFactory.newConnection();
It always show "Exception in thread "main" java.net.SocketException: Connection reset"
Full error trace looks like this:
`
WARN com.rabbitmq.client.TrustEverythingTrustManager - SECURITY ALERT: this trust manager trusts every certificate, effectively disabling peer verification. This is convenient for local development but offers no protection against man-in-the-middle attacks. Please see https://www.rabbitmq.com/ssl.html to learn more about peer certificate verification.
Exception in thread "main" java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:313)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:340)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:789)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:1025)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:477)
at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:471)
at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:925)
at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1295)
at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:125)
at java.base/java.io.BufferedOutputStream.implFlush(BufferedOutputStream.java:251)
at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:239)
at java.base/java.io.DataOutputStream.flush(DataOutputStream.java:128)
at com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHandler.java:160)
at com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHandler.java:170)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:305)
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:64)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:156)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1106)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1063)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1021)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1182)
at com.java.rabbitmq.rabbitmqdemo.directMode.Producer.main(Producer.java:52)
`
The code works like this:
char[] keyPassphrase = "bunnies".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("C:\\Users\\key\\client_key.p12"), keyPassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keyPassphrase);
char[] trustPassphrase = "123456".toCharArray();
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(new FileInputStream("C:\\Users\\key\\rabbitstore"), trustPassphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(tks);
SSLContext c = SSLContext.getInstance(c);
c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.56.102");
connectionFactory.setPort(5671);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
connectionFactory.useSslProtocol("TLSv1.2");
Connection conn = connectionFactory.newConnection();
Channel channel = conn.createChannel();
`
Config file:
listeners.ssl.default = 5671
ssl_options.verify = verify_peer
ssl_options.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem
ssl_options.certfile = /etc/rabbitmq/ssl/server_certificate.pem
ssl_options.keyfile = /etc/rabbitmq/ssl/server_key.pem
ssl_options.fail_if_no_peer_cert = true
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem
management.ssl.certfile = /etc/rabbitmq/ssl/server_certificate.pem
management.ssl.keyfile = /etc/rabbitmq/ssl/server_key.pem
management.listener.ssl = true
management.ssl.password = bunnies
I've tried to modify config file multiple times, but it didn't work.
RabbitMQ Connection reset Exception
RabbitMQ Connection reset
Java rabbitmq SSL issue java.net.SocketException: Broken pipe (Write failed)
I've also tried these solution, but they didn't work, either.

Why is the performance of SSL different in a loop value in java

I want to calculate the time which the ssl(client) needs to establish a connection with a server and make the Handshake. Here is my code and it works fine.
private boolean SslTlsConnection() throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException {
KeyStore client = KeyStore.getInstance("JKS");
client.load(new FileInputStream(currentPath + "clientcert.keystore"), Password.toCharArray());
KeyStore trust = KeyStore.getInstance("JKS");
trust.load(new FileInputStream(currentPath + "myTrustStore.keystore"), Password.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(client, Password.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trust);
SSLContext sc = SSLContext.getInstance("SSL");
TrustManager[] trustManagers = tmf.getTrustManagers();
sc.init(kmf.getKeyManagers(), trustManagers, new java.security.SecureRandom());
SSLSocketFactory ssf = sc.getSocketFactory();
sslsocket = (SSLSocket) ssf.createSocket(Properties.host, Properties.portNumber);
sslsocket.startHandshake();
System.out.println("Handshaking Complete");
System.out.println("Just connected to " + sslsocket.getInetAddress() + "\n");
transport = new IOTransport(sslsocket);
return false;
}
private void close(){
sslsocket.close();
}
I am just curious about the performance. I run multiple connections in a loop and i am calculating the time ssl needs to do the handshake. My question is why the first time which client connect with ssl take so long time in compare with others. Did i something wrong?
for (int i = 1; i < loopvalue; i++) {
long elapseTime = System.currentTimeMillis();
SslTlsConnection()
long elapseTime = (System.currentTimeMillis() - elapseTime);
close();
}
I've tried tests . Here are the results
SSL_Execution_Time
First Execution Time 453ms
Second Execution Time 85ms
Third Execution Time 90ms
The initial ssl handshake only takes place once. The client and server agree on the protocol (ssl vs tls) and the cyphers and they exchange the keys. So a hit is taken on the initial handshake. After that the only thing that happens is the encryption and decryption using the already exchanged keys.
http://www.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm

Update Ciphers list in JAVA windows

I need to send a secured request using java(jre1.8.0_65) on my Windows,
I used the below code to configure my certs and key factory.
KeyStore ks = KeyStore.getInstance("PKCS12");
//FileInputStream fis = new FileInputStream("certs/tester1024.pfx");
InputStream ins = this.getClass().getClassLoader()
.getResourceAsStream("certs/tester1024.pfx");
ks.load(ins, "1234".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SUNX509");
kmf.init(ks, "1234".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
URL obj = new URL(httpURL);
HttpURLConnection connection = (HttpURLConnection) obj.openConnection();
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection)connection)
.setSSLSocketFactory(sc.getSocketFactory());
}
connection.setRequestMethod(method);
responseCode = connection.getResponseCode();
the above code works but the list of Ciphers sent Client in the "CLIENT HELLO" does not include the Cipher TLS_RSA_WITH_AES_256_CBC_SHA256.
it includes this TLS_RSA_WITH_AES_128_CBC_SHA256
In the Client Hello Ciper list, I want this Cipherto be included.
Please let me do I need to update any thing related to JAVA on windows, because on linux same java application includes both the Ciphers.

java establish sslsocket use .cer file

I am new to Java and SSLSocket. I want to use a specified .cer file to establish a SSLSocket in client part. I search it in google, but doesn't find good solution to it. And here is my code:
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("myCer.cer"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// 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);
SSLSocket sock = (SSLSocket)context.getSocketFactory().createSocket("...",21000); //"...": here I ignore the host name. The address and port is right.
sock.setUseClientMode(true);
if(sock.isConnected()) {
System.out.println("Connected...");
}
else
{
System.out.println("Connect Fails...");
}
Login.pbLogin login = Login.pbLogin.newBuilder().setUserID("dbs")
.setPassword("abcd1234")
.setNewPassword("")
.setClientVersion("1.0.0.0")
.setRestarted(true)
.build();
OutputStream outputStream =sock.getOutputStream();
byte[] b1=login.getClass().getSimpleName().getBytes("UTF-8");
byte[] b2=login.toByteArray();
byte[] bytes = ByteBuffer.allocate(4).putInt(b1.length + b2.length).array();
outputStream.write(bytes);
outputStream.write(b1); //login.getClass().getSimpleName().getBytes("UTF-8")
outputStream.write(b2); //login.toByteArray()
outputStream.flush();
byte[] content = new byte[100];
int bytesRead = -1;
InputStream inputStream = sock.getInputStream();
String str;
while(( bytesRead = inputStream.read( content) ) != -1){
System.out.println("OK ,receive.....");
// str = new String(Arrays.copyOfRange(content,0,bytesRead), StandardCharsets.UTF_8);
//System.out.println(str);
}
I use TCPViewer to see, the SSLSocket is in Established state, but when executing outstream.write , the SSLsocket will be Close_wait state and cause exception:
Exception in thread "main" java.net.SocketException: Software caused connection abort: socket write error.
So I couldn't write the info to server, and exit program. I guess the SSLSocket is not established successfully, but Tcpviewer show it is established early, and it's in Connected state(print "connected."). But when try to write the outputstream, it will in Close_wait state. Could you help me to sort it out?
Then I found the reason today. The code has no issue, the reason is that server part can't parse the protocol buffer (pblogin) correctly, which causes exception, so it close the socket. As a result , the state will be in close_wait.Since I find the reason , wish I can solve it by myself.

SSL server socket and handshake with known certificate

I am new to SSl server sockets. All I am tying to do is to read data over SSL.
My application listens on port 8000. Please give me few steps on how I can do this. When I have a certificate (on my disc), how can I establish the SSL server socket and read from client ?
Here are my steps
1) reading server.crt from file and making X509Certificate (has public certificate and private key)
2) Getting instance of JKS keystore
3) Get instance of context
4) create server socket over the port (8000)
InputStream in = new DataInputStream(new FileInputStream(new File("server.crt")));
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(in);
in.close();
ks.setCertificateEntry("dts", cert);
char[] newpass = "password".toCharArray();
String name = "mykeystore.ks";
FileOutputStream output = new FileOutputStream(name);
ks.store(output, newpass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "password".toCharArray());
try{
System.setProperty("javax.net.ssl.keyStore","mykeystore.ks");
System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.debug","all");
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory sslServerSocketfactory = context.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket)sslServerSocketfactory.createServerSocket(8000);
SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
InputStream dataIN = sslSocket.getInputStream();
byte[] hello = new byte[20];
dataIN.read(hello);
System.out.println(new String(hello));
dataIN.close();
} catch (IOException e){
e.printStackTrace();
}
I got the answer for my question, I did research on how to setup my own keystore with self signed certificate. This way helped me.
ping me for a detailed solutions.

Categories