How to communicate the TLS or SSL protocol with Volley library
To reinforce app's security, I have to change HTTP protocol to TLS protocol when communicating with server.
I'm using Volley library to communicate with server.
So, Let me introduce how to communicate TLS protocol with Volley library.
1. Define TLSSocketFactory class
public class TLSSocketFactory extends SSLSocketFactory {
public static final String TAG = "TLSSocketFactory";
private SSLSocketFactory internalSSLSocketFactory;
private TLSSocketFactory(){
// Private constructor to prevent direct instantiation
}
public static TLSSocketFactory createInstance() throws KeyManagementException, NoSuchAlgorithmException {
TLSSocketFactory instance = new TLSSocketFactory();
instance.initialize();
return instance;
}
private void initialize() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
Logger.d(TAG, "getDefaultCipherSuites");
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
Logger.d(TAG, "getSupportedCipherSuites");
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
if(s == null) {
throw new IllegalArgumentException("Socket s cannot be null");
}
if(host == null) {
throw new IllegalArgumentException("host cannot be null");
}
if(port < 0) {
throw new IllegalArgumentException("port must be positive");
}
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
if(host == null) {
throw new IllegalArgumentException("host cannot be null");
}
if(port < 0) {
throw new IllegalArgumentException("port must be positive");
}
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
if(host == null) {
throw new IllegalArgumentException("host cannot be null");
}
if(port < 0) {
throw new IllegalArgumentException("port must be positive");
}
if(localHost == null){
throw new IllegalArgumentException("localHost cannot be null");
}
if (localPort < 0) {
throw new IllegalArgumentException("localPort must be positive");
}
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
if(host == null) {
throw new IllegalArgumentException("host cannot be null");
}
if(port < 0) {
throw new IllegalArgumentException("port must be positive");
}
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
if (address == null) {
throw new IllegalArgumentException("address cannot be null");
}
if (port < 0) {
throw new IllegalArgumentException("port must be positive");
}
if (localAddress == null) {
throw new IllegalArgumentException("localAddress cannot be null");
}
if (localPort < 0) {
throw new IllegalArgumentException("localPort must be positive");
}
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
String[] enabledCipherSuites = {
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
};
((SSLSocket)socket).setEnabledCipherSuites(enabledCipherSuites);
}
if (socket instanceof SSLSocket) {
Log.d(TAG, "Enabled Cipher Suites: " + Arrays.toString(((SSLSocket) socket).getEnabledCipherSuites()));
}
return socket;
}
}
2. Initialize RequestQueue
public RequestQueue getRequestQueue()
{
Logger.d(TAG, "getRequestQueue");
if (mRequestQueue == null)
{
Cache cache = new DiskBasedCache(mContext.getCacheDir(), MAX_CACHE_SIZE);
try{
Network network = new BasicNetwork(new HurlStack(null, TLSSocketFactory.createInstance()));
mRequestQueue = new RequestQueue(cache, network,1);
mRequestQueue.addRequestFinishedListener(listener);
} catch (Exception e) {
Network network = new BasicNetwork(new HurlStack());
mRequestQueue = new RequestQueue(cache, network,1);
mRequestQueue.addRequestFinishedListener(listener);
}
}
return mRequestQueue;
}
I assume that RequestQueue is singleton object.
3. Call api
Now, we can use TLS protocol when communicating server.
So, we enjoy our app with secure environment.
0 댓글