Android Network Programming Series 1: JavaSecurity JSSE (SSL/TLS), javasecurityjsse
AbstractTo:
Java Security has been in Java for a long time and is a very important and independent forum. It contains many knowledge points, such as MD5 and DigitalSignature. Android is outside Java Seurity, extended an android. security Package, which provides the KeyChain. It contains three major specifications: JavaCryptography Extension (abbreviated as JCE), JCE content including encryption and decryption, key exchange, Message Digest (such as MD5 ), key management. Most of the content involved in this article belongs to the scope of JSSE. The content of JSSE is the SSL/TLS of the Java layer. Simply put, you can use JSSE to create an SSL/TLS socket. JavaAuthentication and Authorization Service (JAAS). JSSA is related to authentication/Authorization. This part of content is less exposed on the client. In the preceding three sub-modules or specifications, JCE is the largest part of JavaSecurity. The other two sub-modules JSSE and JAAS depend on it, for example, if SSL/TLS needs to encrypt and decrypt data using a key during work, the creation and use of the key depend on the JCE submodule. However, this article will focus on the SSL/TLS protocol in the main JSSE section, focusing on the security and communication details of the SSL/TLS Protocol. At the same time, we will compare and explain this application in Android or Java programs.
I. Introduction
SSL (Secure Socket Layer) is a Secure Socket Layer developed by Netscape to ensure Secure transmission protocols on the Web, the purpose is to provide confidentiality, authentication, and data integrity assurance for network communication. With the Encryption technology, data can be captured and eavesdropped during network transmission. It has been widely used for identity authentication and encrypted data transmission between Web browsers and servers. The SSL protocol is located between the TCP/IP protocol and various application layer protocols to provide security support for data communication. SSL has become an industrial standard for secure Internet communication. The original SSL versions (SSL 1.0, SSL2.0, and SSL 3.0) were designed and maintained by Netscape. Starting from version 3.1, the SSL protocol was officially taken over by the Internet Engineering Task Team (IETF, and changed its name to Transport Layer Security (TLS). Since its development, TLS 1.0, TLS1.1, and TLS1.2 are available. As mentioned in the TLS name, the SSL/TLS Protocol only ensures the security of the transport layer. At the same time, due to the characteristics of the Protocol (digital certificate mechanism), SSL/TLS cannot be used to protect multi-hop end-to-end communication, but can only protect point-to-point communication. The SSL/TLS Protocol provides the following security goals: Authentication-using digital certificates to authenticate the identity of servers and clients to prevent identity forgery, ensure that data is sent to the correct client and server for confidentiality-protect the integrity of third-party eavesdropping with encryption-protect data integrity with message authentication code (MAC, protection against message tampering and replay-the SSL/TLS protocol is designed as a two-phase protocol to prevent replay attacks to achieve these security objectives, which is divided into the handshake and application phases: the handshake stage is also called the negotiation stage. At this stage, the client and the server will authenticate the identity of the other party (depending on the PKI system and use digital certificates for Identity Authentication ), negotiate the security parameters, cipher suite, and MasterSecret used in communication. All keys used for subsequent communications are generated through MasterSecret. After the handshake stage is complete, the application stage is started. In the application phase, both parties use the key negotiated during the handshake phase for secure communication. The SSL/TLS Protocol has a highly modular architecture and is divided into many sub-protocols, as shown in:
(Key), which has 48 bytes. The first two bytes indicate the maximum Protocol version supported by the client, and the last 46 bytes are randomly selected. Both the key and client-side Public Key call the server-side public key that is included in the previous certificate or passed in ServerKeyExchange for encryption at the same time, and then the message will be sent to the server along with the ClientKeyExchange, the server will use its own private key to decrypt the "symmetric password", which will be used as a Data Encryption Algorithm for future communication between the two, ensuring the security of data transmission. If the selected key exchange algorithm is DH or DHE, there may be two situations: Implicit DH public value: Included in the Certificate message; display DH public value: the public value is part of the message.
CertificateVerify: this message is used to prove that the client has the private key of the client certificate submitted previously. When two-way authentication is used, this message will carry a client to generate a number with its own private key. After receiving this data, the server will decrypt and verify the public key of the client. ChangeCipherSpec Protocol: the client sends a message indicating that the handshake protocol has been completed and switched to the encryption mode;
Finished: indicates that the handshake stage is over. This is the first message to be protected by a negotiated algorithm and key. Because a message is encrypted with a negotiated key, it can be used to confirm the negotiated key. At the same time, the Finished message contains a verify_data domain, which can be used to verify the information sent and received before. The Verify_data field is the output of a PRF function (pseudo-random function ). The input of this pseudo-random function is: (1) Two hash values: One SHA-1 and one MD5, which are used to exchange all messages during the previous handshake.
Encryption and hashing
(Message Digest). Here, the server can verify the integrity of the transmitted data based on the hash value and MD5 value of the data. (2) the MasterSecret is generated by the master key. After the server receives the ChangeCipherSpec and Finished messages from the client, it also sends a ChangeCipherSpec message. The server also switches to the encryption mode, and the handshake protocol ends. At the same time, a Finished statement will be sent to indicate that the client-side Finished request has been received to officially end the handshake. In addition, Finished messages cannot be sent before ChangeCipherSpec. We can hardly find that SSL/TSL communication protocols are actually two algorithms: symmetric encryption and asymmetric encryption. During the protocol handshake, both parties obtain the public key of each other to parse the data and generate and obtain the next communication key. Here is an asymmetric encryption process. Next, use the generated Communication Key to decrypt the communication data. This is a symmetric encryption process. In addition, we also need to know the following terms:
Key:
It belongs to the scope of JCE and can be divided into symmetric keys and asymmetric keys. Symmetric keys are the keys used by both parties to encrypt data. Asymmetric keys are the public and private keys. Its internal representation is a class, and its external representation is a bit string. The key is used to encrypt and decrypt data, just like an unlocked key.
Symmetric encryption (Symmetric cryptography):
It is necessary to apply the same key on both sides to encrypt and decrypt the message algorithm. common key algorithms include Data Encryption Standard (DES), triple-strength DES (3DES), Rivest Cipher 2 (RC2) and Rivest Cipher 4 (RC4 ). Because the symmetric algorithm is relatively effective, it is used to encrypt sensitive data in the SSL session through the process key algorithm.
Asymmetric encryption (Asypolicric cryptography):
That is, the key is composed of the key-pair, and the Public key is transmitted to the private key of the other party for storage. The public key and private key algorithms are reciprocal. One is used for encryption and the other can be decrypted. Common algorithms include Rivest Shamir Adleman (RSA) and Diffie-Hellman (DH ). Asymmetric algorithms are used to encrypt a small amount of data, such as key encryption, rather than communication encryption for a large amount of data.
Encryption and hashing (Cryptographic Hash Functions):
The encryption hash function is similar to the checksum function. The difference is that checksum is used to detect unexpected data changes while the former is used to detect intentional data correction. After data is hashed, a small string of BITs is generated. A small change in data will lead to a change in the hash string. When sending encrypted data, SSL uses the encrypted hash function to ensure data consistency and block the integrity of damaged third-party communication data. Common SSL hashing algorithms include Message Digest 5 (MD5) and Secure Hash Algorithm (SHA ).
Message authentication code (Message Authentication Code):
The message authentication code is similar to the encrypted hash function. On the basis of the hash encryption machine, it needs to contact the data generated by the key information and the encrypted hash function, that is, the hash message authentication code (HMAC ). If A wants to ensure that the message sent to B is not corrected by C, he must follow the steps below -- A first generates an HMAC value; add it to the back of the original message. Encrypt the message body with the key for communication between A and B, and then send it to B. B. After receiving the message, decrypt it with the key. then create an HMAC value for the communication data and compare the two values to determine whether the message is corrected during transmission.
Number (Digital Signature):
After a message's encrypted hash is created, the hash value is encrypted with the sender's private key. The encryption result is called a number.
Iii. Practical Application
This case is divided into two parts: one is the server and the other is the client. The server prints the received client data, that is, a string sent by the client. Server:
Void initServer () {
Try {
// get the security environment of SSL protocol, or TLS
SSLContext sContext = sslcontext.getinstance ("SSL");
// get the secret key memory in JKS algorithm format - common are JKS, JCEKS,and PKCS12. Among them the function is relatively complete JCEKS
KeyStore = KeyStore. GetInstance ("JKS");
AssetManager manager = mContext. GetAssets ();
InputStream is = manager.open("test_key_store");
// import the certificate into the secret-key memory and configure it with an open password. Sometimes we need to have different types of secret keys and need multiple secret key stores to store them
Store. The load (is, "Kevin". ToCharArray ());
Is the close ();
// in order to manage more than one or more secret key memories, the concept of a secret key manager, which is dedicated to managing more than one or more secret key memories, has been introduced
A KeyManagerFactory factory. = a KeyManagerFactory getInstance (a KeyManagerFactory getDefaultAlgorithm ());
// configure a get password for each key manager's installed key store
Factory. The init (store, "123456". ToCharArray ());
/ * *
* initializes the SSL protocol security environment. The init function takes three arguments, the first of which is the KeyManager array, and the server side needs to sign the certificate with the private key stored init
* the second is the TrustManager array, and the third is the SecureRandom, which is used to create random Numbers
* for the server side, it does not need to verify the client certificate, so obviously the first parameter is used to create the server Socket, and the second parameter is used to create the client Socket.
* /
Scontext.init (factory.getkeymanagers (), null, null);
// the following is to configure the IP and port to link
InetAddress = inet4address.getlocalhost ();
SSLServerSocket serverSocket = (SSLServerSocket) sContext. GetServerSocketFactory () createServerSocket (8666, 1, address);
The Socket Socket = serverSocket. The accept ();
InputStream = in the socket. GetInputStream ();
Byte [] data = new byte[1024];
Int count = in.read (data);
Log. I ("TAG", "DATA:"+new String(DATA, 0, count));
In the close ();
Socket. The close ();
ServerSocket. Close ();
} catch (NoSuchAlgorithmException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (KeyStoreException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (CertificateException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (IOException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} the catch (UnrecoverableKeyException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (KeyManagementException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
}
}
Client:
Void initClient () {
Try {
// get the secure environment of SSL protocol
SSLContext sContext = sslcontext.getinstance ("SSL");
// get the secret key memory of BKS algorithm format - a common format in Android
KeyStore = KeyStore. GetInstance ("BKS");
AssetManager manager = mContext. GetAssets ();
/ / here is a certificate created using the Java native tool keytool in the project assert file
InputStream is = manager.open("test_key_store");
// import the certificate into the secret-key memory and configure it with an open password. Sometimes we need to have different types of secret keys and need multiple secret key stores to store them
Store. The load (is, "Kevin". ToCharArray ());
Is the close ();
TrustManagerFactory TrustManagerFactory = TrustManagerFactory. GetInstance (TrustManagerFactory getDefaultAlgorithm ());
// initialize the trustManagerFactory by importing the contents of the certificate
TrustManagerFactory. Init (store);
/ * *
* initializes the SSL protocol security environment. The init function takes three arguments, the first is the KeyManager array,
* the second is the TrustManager array, and the third is the SecureRandom, which is used to create random Numbers
* for the client side, it needs to verify the server side certificate, so it only needs to go to the second parameter (also can not be filled in).
* /
Scontext.init (null, trustmanagerfactory.gettrustmanagers (), null);
// the following is to configure the IP and port to link
InetAddress = inet4address.getlocalhost ();
SSLSocket socket = (SSLSocket) sContext. GetSocketFactory () createSocket (address, 8666);
OutputStream out = socket. GetOutputStream ();
String data = "hello I'm spencer but you can call me Kevin ";
Out. Write (data. GetBytes ());
Out. The close ();
Socket. The close ();
} catch (NoSuchAlgorithmException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (KeyStoreException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (CertificateException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (IOException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
} catch (KeyManagementException e) {
// TODO auto-generated catch block
E.p rintStackTrace ();
}
}
Iv. Summary
This is the end of JSSE introduction. The content about JCE will be sorted out later. If any of the above descriptions are incorrect or you have any questions, you can discuss them together!