Background
Before we start, let's have a general overview of the SSH protocol, which is more useful for our understanding of this article. The first thing to mention is the computer network protocol, the so-called computer network protocol, the simple is to define a set of standards and rules, so that different computers can carry out normal network communication, not appear on one machine issued instructions to another machine became an unrecognized garbled, SSH is one of the many protocols. After the advent of the classic seven-layer OSI model (Open System interconnection Reference models), the compatibility problem of network interconnection is solved, which divides the network into three parts of service, interface and protocol, and the Protocol is how to realize the service of this layer. SSH, Telnet protocol is mainly used in the user layer (1 Dark section shown), that is, the application layer, the presentation layer and the session layer.
Figure 1. Seven Layer OSI model
Back to top of page
Introducing SSH what is SSH
SSH (Secure Shell Protocol) is a protocol for secure remote logins and other secure network services in an unsecured network. This definition is derived from the IETF (Internet Engineering Task force). In the TCP/IP five layer model, SSH is a security protocol that is applied to the application and transport layers.
Advantages of SSH
Traditional network transmission, such as: Telnet, FTP, etc., is the use of plaintext transmission of data and passwords, so it is easy to be hackers such as the middle people sniffing into the transmission process of data, greatly reducing the network communication security. The SSH protocol uses data encryption to establish a secure network transmission channel, which enhances the security of the data during the network transmission. The complexity of data encryption can result in more network resources being consumed. SSH compresses the encrypted data to reduce the network bandwidth footprint. To sum up, the advantages of SSH are as follows:
- Data encryption for increased security
- Data compression to improve the speed of network transmission.
Architecture of SSH
After a preliminary understanding of SSH, let's take a look at how the SSH protocol is secure for data communication. First look at the main architecture of the SSH protocol:
Figure 2. The composition of the SSH protocol
Transport Layer protocol: typically run on top of TCP/IP, is the foundation of many secure network services, providing data encryption, compression, server authentication, and data integrity assurance. For example, public key algorithm, symmetric encryption algorithm, message authentication algorithm and so on.
User authentication protocol: run on the SSH Protocol's transport layer, to detect whether the client's authentication method is legitimate.
Connection protocol: Run on the user authentication layer, provide the interactive login session, the execution of remote command, forwarding TCP/IP connection and other functions, to provide a secure, reliable encrypted transmission channel.
Application of SSH
In the actual work, many target machines are often not directly operated by us, these machines may be a server in a company room, or a customer environment far across the ocean. At this point we have to telnet to the target machine to perform the operations we need, which not only reduces operational costs, but also improves execution efficiency. Our common Telnet protocol is SSH, Telnet, and so on. As mentioned above, Telnet uses the plaintext transmission, so the ulterior motives of the "middleman" there is an opportunity, relative to the Telnet protocol, the security of the SSH protocol is much higher. This feature also allows the SSH protocol to be quickly promoted, and many large projects are used more or less in this protocol. The following article mainly discusses the SSH protocol user authentication protocol layer, and the following unified the remote machine is called the server (server), the local machine is called the client.
Authentication protocol for SSH
There are several common authentication methods for SSH protocols:
- Password-based authentication method (password authentication method) for remote machine logon verification by entering a username and password.
- A public key-based security authentication Method (authentication), which implements a user's login verification by generating a set of keys (Common Key/private key).
- Based on the keyboard interaction authentication method (Keyboard interactive authentication method), the server sends the prompt message to the client, which is then sent back to the server by the client according to the corresponding information by manual input.
How the SSH authentication protocol works
SSH's main workflow:
Figure 3. SSH Login Workflow
Through this flow chart, we can see that in the user to the remote machine access, first, is the server side of a connection handle, which can be understood as a session, and then the client can get some basic information of the server through this handle, such as the version of SSH, The version information of the server, as well as some cryptographic algorithm information. Secondly, the client can analyze this information to match the current client's encryption algorithm, verify whether the method conforms to the configuration of the server, and then obtain a mutually acceptable way, which can be considered as a negotiation between the two sides. Finally, when the two sides agree, a secure channel is really built up, at this time the user can do the desired operation of the remote machine. When we have a certain understanding of this, we can initially judge, in peacetime work, we through the SSH protocol to connect a remote machine error, the problem arises in which process. The following is a detailed Java example to explain how the user authentication method.
Back to top of page
Java implementations of common authentication methods
Before we start, we have to do some preparation for the environment.
- A local machine, operating system that Windows uses as a client
- A remote machine, operating system Linux is used as a server-side
- OpenSSH Tools
- Putty Tools
First, make sure that the OpenSSH tool is already installed on the server side, and that the SSH service is started and can be viewed with the following command:
See if the OpenSSH is already installed
Listing 1. OpenSSH version
# Rpm-qa | grep ssh openssh-5.1p1-41.31.36 openssh-askpass-5.1p1-41.31.36
Check to see if the SSH service is started.
Listing 2. Service Status of SSH
#/etc/init.d/sshd status
The Checking for service sshd running tries to connect to the remote machine using the Putty tool on the Windows machine, client side.
Figure 4. SSH Connection Successful
So far, we have been able to connect to this remote machine normally. Below we are going to implement our own remote login operation in the way of Java code.
Verify Service Name
Some message codes are defined in the SSH protocol, while 50 to 79 of the code is reserved for use by the User authentication protocol layer, and more than 80 of the numbers are for the protocol to run, so if the message code we get is this range before the user authentication protocol is validated, SSH returns an error message and disconnects the connection. For example, the following messages correspond to the code number:
Ssh_msg_userauth_request 50: The user sends a validation request.
Ssh_msg_userauth_failure 51: User authentication request failed.
Ssh_msg_userauth_success 52: User authentication request succeeded.
Then for different authentication methods, there are their own message code.
Each time a client sends a request, the server checks whether the current service name and username are valid, and if the current service name or username is unavailable, the server will immediately disconnect the request.
The following is a request for service name validation, which is sent in the following format:
BYTE ssh_msg_service_request
String service name in US-ASCIII
The specific code is as follows:
Listing 3. Class Authservicerequest
Package Com.my.test.ssh2.auth; Import Com.my.test.ssh2.common.ProcessTypes; public class Authservicerequest { private String serviceName; Public Authservicerequest (String serviceName) { this.servicename = serviceName; } /** * Get authentication message for specified server name * @return request– returns a hexadecimal message **/public byte [] getrequestmessage () { byte [] request; Processtypes type = new Processtypes (); Type.asbyte (authconstant.ssh_msg_service_request); Type.asstring (serviceName); Request = Type.getbytes (); return request; }}
The message sent after the conversion is as follows:
[5, 0, 0, 0, 12, 115, 115, 104, 45, 117, 115, 101, 114, 97, 117, 116, 104]
The algorithm is then encrypted and sent to the server side.
The service name used by the current protocol is "Ssh-userauth" and if the client is not requesting the service name, the server will report the following error:
Listing 4. Service Name exception
caused By:java.io.IOException:Peer sent DISCONNECT message (Reason code 2): Bad service Request Demo-ssh-auth
If the client passes the validation of the service name, the next step is to implement the specific authentication method. The flowchart is as follows:
Figure 5. Authentication class Diagram
The TransportManager class is the business logic used to process the transport protocol layer. Here the main processing of data decryption, encryption, compression and other operations, the specific implementation of these functions are mainly through the Transportcontrol class to complete, Trasportcontrol class will be based on the client and server-side negotiated data algorithm to select specific algorithms such as Sha-1, MD5 and so on. Data processed through the Transportcontrol class is stored in the Packets class, generating a list of packets that provide the necessary data information for the AuthManager class. The Connect class is the business logic used to process the connection protocol layer. It is mainly used to get the connection handle of a remote machine, to generate a secure channel, to initialize the data of the TransportManager class, and so on. The AuthManager class is the business logic used to process the authentication protocol layer. Mainly is the different login authentication method request and the request reply from the server side to do the processing, through the client chooses the different authentication way to invoke the different authentication way realization class, for example Authrequestbypassword class defines through the password Authentication way realization.
Figure 6. Certification Protocol Flowchart
First, a thread is used to receive the encrypted packets sent from the server, then the packet is decrypted by the algorithm and placed on a modeled stack (Packet list), while another thread listens to the current Packet list for available packets, and the analytical processing includes whether the data packet is legitimate, whether it satisfies some authentication algorithm, etc. If the packet contains authentication methods that do not match the authentication method of the current client request, the client loses the connection to the server. Conversely, if the authentication method that the client requests is included in the authentication method that the server opens, the client returns a successful request to the server and establishes a connection session.
None authentication method
No authentication method (none authentication), this authentication method is usually used when the first request is sent, because through this authentication method, we can get a list of all authentication methods supported by the current server side, With this list we can verify that the authentication method we want to use is supported by the server side. Of course, if the remote target machine supports this none authentication method, then the client directly gets a session connection, but this authentication method is not recommended in the SSH protocol.
The implementation code is as follows:
Listing 5. Class Authrequestbynone
package com.my.test.ssh2.auth; Import Com.my.test.ssh2.common.ProcessTypes; public class Authrequestbynone {private String userName; Private String ServiceName; Public Authrequestbynone (String serviceName, String user) {this.servicename = ServiceName; This.username = user; /** * Obtain authentication message for the specified server name and user name * @return Request-Returns a hexadecimal message * */public byte [] Getrequestme Ssage () {byte [] request; Processtypes type = new Processtypes (); Type.asbyte (authconstant.ssh_msg_userauth_request); Type.asstring (UserName); Type.asstring (ServiceName); Type.asstring (Authconstant.ssh_none_authentication_method); Request = Type.getbytes (); return request; } }
As can be seen from Flowchart 6, when we send a none authentication method, if the server does not support the authentication of none, then the client can obtain the server-side authentication method list. First, the packet information returned by the server is parsed, for example:
[51, 0, 0, 0, 34, 112, 117, 98, 108, 105, 99, 107, 101, 121, 44, 103, 115, 115, 97, 112, 105, 45, 119, 105, 116, 104, 45, 109, 105, 99, 44, 112, 97, 115, 115, 119, 111, 114, 100, 0]
After the client's algorithm is parsed, we can get a packet containing the following information: (The specific description of the algorithm principle is defined in the Transport Layer protocol, not the scope discussed in this article.) )
Code 51, which indicates that the user authentication request failed.
The authentication methods supported by the current server are recorded from 5th to 34th bits, and a comma-separated authentication string of PublicKey, gssapi-with-mic, password is obtained after parsing.
The last 0 indicates that the current request failed, but not that the entire connection was broken.
The specific algorithm for parsing the packet is as follows:
Listing 6. Parsing data algorithms
((arr[pos++] & 0xff) << 24) | ((arr[pos++ & 0xff) <<) | ((arr[pos++] & 0xff) << 8) | (arr[pos++] & 0xff);
For the server side, it will give a feedback on the client's request, indicating whether the current request is successful.
The data format is as follows:
byte ssh_msg_userauth_failure name-list authentications that can continue Boolean partial success
So, this just explains the results of the data parsed from the server side.
The implementation part of the code is as follows:
Listing 7. initialization function
Public Boolean Initialize (String userName) throws ioexception{//Preprocessing service name request Authservicerequest Servicerequest = new Authservicerequest (authconstant.ssh_service_name); IManager Transmanager = Managerfactory.getmanager (Constant.transport_layer); Transmanager.sendmessage (Servicerequest.getrequestmessage ()); Processing a message request without authentication Authrequestbynone Authnone = new Authrequestbynone (authconstant.ssh_conn_service_name,user Name); Transmanager.sendmessage (Authnone.getrequestmessage ()); byte[] message = GetMessage (); Verifies whether the current service name is valid if (!isaccepted (message)) {return false; }//Get request packet with no authentication method message = GetMessage (); Verifies if the current request is successful if (isrequestfailed (message)) {return false; } return true; } Private Boolean isrequestfailed (Byte [] messages) throws IOException { if (messages[0] = = authconstant.ssh_msg_userauth_success) {return true; } if (messages[0] = = authconstant.ssh_msg_userauth_failure) {authfailure FAILURE = new Aut Hfailure (Messages); authentications = Failure.getauththatcancontinue (); Ispartialsuccess = Failure.ispartialsuccess (); return false; } throw new IOException ("Unexpected SSH message (type" + messages[0] + ")"); }
When the client obtains the authentications array, the client can verify that the current user is using a remote login authentication method that is supported by the server. If it is then sent a matching authentication method, which returns the login authentication success, otherwise failed and printed a reasonable error message. The following is an example of password authentication method for further explanation.
Password Authentication method
For the password authentication method, its data request format is as follows:
BYTE ssh_msg_userauth_request String user name string service name string "Password" Boolean FALSE String plaintext password in ISO-10646 UTF-8 encoding
The implementation of the specific class is similar to the implementation of the None authentication class, except that the Getrequestmessage () method is all different.
Implementation code:
Listing 8. Generate Request Data function
public byte [] Getrequestmessage () { byte [] request; Processtypes type = new Processtypes (); Type.asbyte (authconstant.ssh_msg_userauth_request); Type.asstring (userName); Type.asstring (serviceName); Type.asstring (Authconstant.ssh_password_authentication_method); type.asstring (password); Request = Type.getbytes (); return request; }
Here we need to provide a user password on the server side, this password will be sent to the server side before the algorithm encryption processing. The code to invoke the password authentication method is as follows:
Listing 9. Password Authentication function
public boolean passwordauthentication (string user, String pass) throws ioexception{//initialization please Request Initialize (user); Verify that the specified authentication method is supported by the SSH server if (Verifyauthenticatonmethods (Authconstant.ssh_password_authentication_method)) { return false; }//Call password Authentication mode Authrequestbypassword passwordrequest = new Authrequestbypassword (authconstant.ssh_conn _service_name,user,pass); Send a message request to server side IManager Transmanager = Managerfactory.getmanager (Constant.transport_layer); Transmanager.sendmessage (Passwordrequest.getrequestmessage ()); Get packet from server side byte[] message = GetMessage (); Verifies if the current request is successful if (isrequestfailed (message)) {return false; } return true; }
The client first initializes the operation, including the data encryption algorithm negotiation, obtains the server side support authentication way and so on. Second, the client will check that the current user is using the authentication method is legitimate, and then send a request to the server side, tell the server is currently using password Authentication remote login. Finally, the server returns a packet containing a reply to the request, and if the validation succeeds, the connection can open a secure session. At this point, the resolution of the password authentication method is completed, the next user can be on the remote machine exercises, this part of the specific instructions are in the SSH Connection layer protocol, not the scope of this article.
Back to top of page
Summarize
Space is limited, this article on the password authentication method as an example of the client remote login authentication method of discussion, for other authentication methods will be discussed in a future article. When the client uses SSH protocol for remote login, it provides a lot of common authentication methods, the data structure of each authentication method is slightly different, and also provides the external expansion interface, can customize authentication mode. Through the reading of this article, it can be preliminarily understood that the SSH protocol in the user authentication layer of the basic principles, hoping to readers in the future project development, the use of SSH protocol to help.
Original: http://www.ibm.com/developerworks/cn/java/j-lo-sshauthentication/
Java implementation of SSH protocol client Login authentication Method-Reproduced