Android How to use HTTPS, this article is more important in the Nohttp series, for everyone to introduce the content.
What is HTTPS?
HTTPS (full name: Hyper Text Transfer Protocol over secure Socket Layer) is a security-targeted HTTP channel and is simply a secure version of HTTP. That is, the SSL layer is added under HTTP, the security base of HTTPS is SSL, so the detailed content of encryption needs SSL. It is a URI Scheme (abstract identifier system) with syntax similar to http: System. For secure HTTP data transfer. Https:url indicates that it uses HTTP, but HTTPS has a different default port than HTTP and an encryption/authentication layer (between HTTP and TCP). The system was originally developed by Netscape (NetScape) and built into its browser NetScape navigator, providing an authentication and encryption method of communication. It is now widely used in security-sensitive communications on the World Wide Web, such as finance, online shopping and other areas involving payments.
This time do not install force, we come to a layman, first say the most original HTTPS, and then how the framework framework how to use HTTPS
How does Android use the original Java code with HTTPS
First popularize how Android uses the most primitive Java code to request the network, the great God please pass.
Android with Java development, Java comes with the HTTP API httpurlconnection,android system plus Apache Httpclient, plus later Httpclient in the SDK was deleted by Google, Therefore, we also do not recommend the use of HttpClient to do network requests, so here is also only the way to list httpurlconnection.
First step: Open a connection to an address
Here we open my blog address, using the Get method to request
<code><code><code>url url = new URL ("https://blog.csdn.net/yanzhenjie1003");
HttpURLConnection URLConnection = (httpurlconnection) url.openconnection ();
Urlconnection.setrequestmethod ("GET");</code></code></code>
Step two: Determine the HTTPS request, set the Sslsocketfactory
If it is HTTPS request, then do the security check and so on, here set Sslsokcetfactory, here are two methods, one is to contain the HTTPS certificate, one is no certificate directly allow HTTPS request, and the certificate is not certificate is from the Sslcontext:
<code><code><code><code><code>//set Sslsocketfoactory, there are two kinds: 1. Security certificate required 2. No security certificate required ; Crossing and looking down
if (urlconnection instanceof httpsurlconnection) {//IS HTTPS request
Sslcontext Sslcontext = Sslcontextutil.getsslcontext ();
if (sslcontext! = null) {
Sslsocketfactory sslsocketfactory = Sslcontext.getsocketfactory ();
((httpsurlconnection) urlconnection). Setsslsocketfactory (Sslsocketfactory);
}
}</code></code></code></code></code>
Then sslcontext how to generate it, haha first not urgent, we first put this request process, the certificate load back side to see OH.
Step three: Set the necessary properties
<code><code><code><code><code><code>//Setting properties
Urlconnection.setconnecttimeout (8 * 1000);
Urlconnection.setreadtimeout (8 * +); </code></code></code></code></code></ Code>
Fourth step: Read data, send to main thread, disconnect
<code><code><code><code><code><code>int ResponseCode = Urlconnection.getresponsecode ();
if (Responsecode = = 200) {//Request succeeded
InputStream InputStream = Urlconnection.getinputstream ();
Read result, send to main thread
...
Inputstream.close ();
}
Urlconnection.disconnect ();</code></code></code></code></code></code>
Full code
<code><code><code><code><code><code>url url = new URL ("https://blog.csdn.net/ Yanzhenjie1003 ");
HttpURLConnection URLConnection = (httpurlconnection) url.openconnection ();
Urlconnection.setrequestmethod ("GET");
There are two ways to set up Sslsocketfoactory: 1. Require a security certificate 2. No security certificate required; Crossing and look down
if (urlconnection instanceof httpsurlconnection) {//IS HTTPS request
Sslcontext Sslcontext = Sslcontextutil.getsslcontext ();
if (sslcontext! = null) {
Sslsocketfactory sslsocketfactory = Sslcontext.getsocketfactory ();
((httpsurlconnection) urlconnection). Setsslsocketfactory (Sslsocketfactory);
}
}
Setting properties
Urlconnection.setconnecttimeout (8 * 1000);
Urlconnection.setreadtimeout (8 * 1000);
int responsecode = Urlconnection.getresponsecode ();
if (Responsecode = = 200) {//Request succeeded
InputStream InputStream = Urlconnection.getinputstream ();
Read result, send to main thread
...
Inputstream.close ();
}
Urlconnection.disconnect ();</code></code></code></code></code></code>
This completes the entire request, in fact, the Android request network so dot code, and then we write a perfect point, and then encapsulate the write parameters, fault-tolerant What, is a small framework. Isn't it simple?
Using popular frames Nohttp how to play HTTPS
With Nohttp not too simple, what pass parameters, file, download and so on, the basic is one or two words will be done.
<code><code><code><code><code><code>Request<string> Request = Nohttp.createstringrequest (URL, requestmethod.post);
Note that the code for setting sslsokcetfactory here is the same
Sslcontext Sslcontext = Sslcontextutil.getsslcontext ();
if (sslcontext! = null) {
Sslsocketfactory socketfactory = Sslcontext.getsocketfactory ();
Httpsrequest.setsslsocketfactory (socketfactory);
Requestqueue.add (0, request, httpListener);//Added to the request queue, waiting for the result to be accepted
}
</string></code></code></code></code></code></code>
We notice that the code that sets the socket above is the same, and the rest is a sentence that the new request object will be finished. Is it simpler than the native?
This framework, called Nohttp, is an Android open-source network framework.
How do I get sslsocketfactory objects?
Whether it is the pure Android code or the Nohttp framework to use the Sslcontext, this guy is responsible for certificate management and trust Manager, we say that HTTPS can have a certificate or no certificate, we look at both cases.
Sslcontext with a security certificate
We put the HTTPS certificate in the assets directory and then load it through the stream:
<code><code><code><code><code><code><code>public Static SSLContext Getsslcontext () {
Generating Sslcontext objects
Sslcontext Sslcontext = sslcontext.getinstance ("TLS");
To load a certificate from the assets
InputStream instream = Application.getinstance (). Getassets (). Open ("Srca.cer");
Certificate Factory
Certificatefactory cerfactory = certificatefactory.getinstance ("the");
Certificate cer = cerfactory.generatecertificate (instream);
Key Store
KeyStore Kstore = keystore.getinstance ("PKCS12");
Kstore.load (null, NULL);
Kstore.setcertificateentry ("trust", CER);//load Certificate into KeyStore
Key Manager
Keymanagerfactory keyfactory = keymanagerfactory.getinstance (Keymanagerfactory.getdefaultalgorithm ());
Keyfactory.init (Kstore, NULL);//load KeyStore to Manager
Trust Manager
Trustmanagerfactory tfactory = trustmanagerfactory.getinstance (Trustmanagerfactory.getdefaultalgorithm ());
Tfactory.init (Kstore);//load KeyStore to trust manager
Initialization
Sslcontext.init (Keyfactory.getkeymanagers (), Tfactory.gettrustmanagers (), New SecureRandom ());
return sslcontext;
}</code></code></code></code></code></code></code>
It should be emphasized that the new SecureRandom () in the last sentence has a bug in the system before Android4.4.
Fixed securerandom bug in Android system
The Apache Harmony 6.0m3 and its previous version of the SecureRandom implementation used in the Java Encryption Architecture (JCA) prior to Android 4.4 have a security vulnerability, specifically in classlib/modules/security/ Src/main/java/common/org/apache/harmony/security/provider/crypto/sha1prng_ Securerandomimpl.java file in the Enginenextbytes () method. When the user does not provide a seed for generating a random number, the program does not correctly adjust the offset, causing the pseudo-random number generator (PRNG) to generate a random sequence of processes that can be predicted.
But happy nohttp internal has fix this bug, if you want to write the framework, I am afraid to write a lot of code to fix this problem, so recommend you crossing or use Nohttp.
Sslcontext without a security certificate
The above see need to need the security certificate of the build Sslcontext, and then do not need the request of the certificate, need two objects, one is Sslcontext (explained above), and the other is Hostnameverifier, as the name implies that the host name matches the meaning, Let's look at the code.
<code><code><code><code><code><code><code><code><code> <code><code><code>public static Sslcontext Getsllcontext () {
Sslcontext sslcontext = null;
try {
Sslcontext = Sslcontext.getinstance ("TLS");
Sslcontext.init (NULL, New Trustmanager[]{new X509trustmanager () {
@Override
public void checkclienttrusted (x509certificate[] chain, String authtype) {}
@Override
public void checkservertrusted (x509certificate[] chain, String authtype) {}
@Override
Public x509certificate[] Getacceptedissuers () {
return new x509certificate[0];
}
}}, New SecureRandom ());
} catch (Exception e) {
E.printstacktrace ();
}
return sslcontext;
}</code></code></code></code></code></code></code></code></ Code></code></code></code>
It's that simple, just pass a null certificate manager to drink a default trust manager.
Next look at Hostnameverifier, since is the host name check, then we directly through:
<code><code><code><code><code><code><code><code><code> <code><code><code><code>private static Hostnameverifier Hostnameverifier = new Hostnameverifier () {
@Override
public boolean verify (String hostname, sslsession session) {
return true;
}
};</code></code></code></code></code></code></code></code>< /code></code></code></code></code>
How does this work? Android native code usage, get Sslcontext method name is different, more sethostnameverifier, and other with the use of security certificates consistent:
<code><code><code><code><code><code><code><code><code> <code><code><code><code><code><code>url url = new URL ("https://blog.csdn.net/ Yanzhenjie1003 ");
HttpURLConnection URLConnection = (httpurlconnection) url.openconnection ();
Urlconnection.setrequestmethod ("GET");
There are two ways to set up Sslsocketfoactory: 1. Require a security certificate 2. No security certificate required; Crossing and look down
if (urlconnection instanceof httpsurlconnection) {//IS HTTPS request
Sslcontext Sslcontext = Sslcontextutil.getsslcontext ();
if (sslcontext! = null) {
Sslsocketfactory sslsocketfactory = Sslcontext.getsllcontextnocertificate ();
((httpsurlconnection) urlconnection). Setsslsocketfactory (Sslsocketfactory);
((httpsurlconnection) urlconnection). Sethostnameverifier (Sslcontextutil.hostnameverifier);
}
}
Setting properties
Urlconnection.setconnecttimeout (8 * 1000);
Urlconnection.setreadtimeout (8 * 1000);
int responsecode = Urlconnection.getresponsecode ();
if (Responsecode = = 200) {//Request succeeded
InputStream InputStream = Urlconnection.getinputstream ();
Read result, send to main thread
...
Inputstream.close ();
}
Urlconnection.disconnect (); </code></code></code></code></code></code></ Code></code></code></code></code></code></code></code></code >
Nohttp usage, the code and the top of the Nohttp load certificate, the same as one more sethostnameverifier:
<code><code><code><code><code><code><code><code><code> <code><code><code><code><code><code><code>Request<string> Request = Nohttp.createstringrequest (URL, requestmethod.post);
Sslcontext Sslcontext = Sslcontextutil.getsslcontext ();
if (sslcontext! = null) {
Sslsocketfactory socketfactory = Sslcontext.getsllcontextnocertificate ();
Httpsrequest.setsslsocketfactory (socketfactory);
Httpsrequest.sethostnameverifier (Sslcontextutil.hostnameverifier);
Requestqueue.add (0, request, httpListener);//Added to the request queue, waiting for the result to be accepted
}</string></code></code></code></code></code></code></code> </code></code></code></code></code></code></code></code></ Code>
If you read through the full text, I believe that the use of Android HTTPS it?
Technical Source: www.shuangyulin.com
How Android uses HTTPS