The DH key exchange of SSH is a set of key exchange algorithms for several complex algorithms. The algorithm called Diffie-hellman-groupx-exchange-shax in RFC4419 (there is another simple Rsax-shax switching algorithm). This paper takes diffie-hellman-group-exchange-sha256 as an example to explain the whole process of key exchange in detail.
The author in the RfC and on the Internet for a long time, but also just to do a general understanding of the implementation of the help is not small. Actually in the implementation process, there are too many details to pay attention, in a lot of details of the differences, need to carry the courage to test. (Forgive me for not looking at OpenSSH source and using the OpenSSL library, I just want to implement the entire SSH myself). In diffie-hellman-group-exchange-sha256 , the type of data is very important, because it involves hash operations, it is necessary to distinguish between good integers and strings and binary. A small difference will result in a hash result is very different, hash wrong after the work is futile.
The key exchange algorithms used in the whole process of diffie-hellman-group-exchange-sha256 are:Diffie-hellman, sha256, Ssh-rsa (or other algorithm negotiated host key, not pure RSA, shrimp told me that SSH is using the rsassa-pkcs1-v1_5 scheme standard ). and to support these encryption algorithms, but also need a lot of basic algorithms: large integer, high-precision operation, fast modulus, discrete algorithm ... (Fortunately, there is a certain ACM foundation, originally was intended to learn and implement the SSH protocol, the results of the algorithm on the road farther and further, this time to exercise their own. After the use of object-oriented technology, and then do not implement the unnecessary bottom, the future involves the safe transmission directly with OpenSSL.
The following is an explanation of each algorithm, first of all, the most important basic data structure and calculation methods:
1,Mpint: A multi-precision integer in twos complement format, stored as one character, 8 bits per character, from high to low, negative highest to 1, positive highest bit to 0 (integer only). The data format is: 4 character length + The numeric value of the length character. For example: a1d8:00 xx A1 D8; 4:00 00 00 02 00 04
2, Multi-large integer : usually 16 in the storage, so easy to use when less conversion, turn the binary system is also very quickly, the implementation is very troublesome, although I have their own large integer template, but ultimately is not assured that I rewrite it with a large integer cryptopp, which is used by others.
3, high-precision Operation : the main implementation of addition multiplication and redundancy, because DH and RSA only need to use multiplication and redundancy.
4, the Fast modular power :D h algorithm and the RSA algorithm will use similar operations: A^b%c. Because B is a large integer, so for his power operation we divide B into two, and then calculate the results of a and a, which saves a lot of unnecessary computations. A few examples: 3^8=3*3*3*3*3*3*3*3 to perform 7 operations. This solution (3^4) * (3^4) = (3^4) ^2= ((3^2) * (3^2)) ^2= ((3^2) ^2) ^2 requires only 3 operations. The first way of time complexity is O (n), the second power of the method time complexity is O (Logn), when B is a 10-bit decimal integer, the first way to calculate the 10^10 times, and the binary power of the way only need to calculate about 30 times. Because we require the remainder, so in the power operation at the same time the modulo operation, also can greatly reduce the computational capacity, otherwise the memory may not fit so large power fruit. The code implementation is given below:
Integer fastpower_comp (integer a,integer b,integer c) {/*sample unused fast powerinteger re=1;for (int i=0;i<b;i++) {R E*=a;re%=c;} return re;*///fast Powerinteger n=c;c=1;while (b!=0) {if (b%2!=0) {b=b-1;c= (c*a)%n;} Else{b=b/2;a= (A*a)%n;}} return C; }
Cryptographic algorithms:
1. Diffie-hellman:
The server first produces two numbers G,P,p is a very large prime number, as a model of the DH algorithm;G is the cipher generator , which is p An original root (does not understand it does not matter), the server sends these two numbers to the client, for the secret key exchange.
The client generates a number (the client's private key)x(0<x<p, but the x should be larger, otherwise the key length generated by the G special hour may be short, the server Rejects), and the e= (g^x)%Pis computed. The resulting e is the client's public key, and the client sends e to the server.
The server is also the same as the client, generating a number y, which computes f=(g^y)%P. Sends the server public key F to the client.
Now the client and server are aware of the other party's public key, the two sides of the other's public key as the base of the modulo power operation, the server computing k1= (e^y)%P, client computing K2= (f^x)%P can prove here K1==k2 , the obtained K value is the secret key exchanged between the two sides.
generation of large primes: I used a method of guessing and enumerating. The number of the numbers in the Sieve method is known that the higher the probability of successive primes, the longer the continuous length. We can randomly generate a large number (preferably odd), and then determine whether the prime is a prime, if not, the number plus two to judge, until the judge is a prime, and then each time to take the prime can be added to the result of the second judgment (the probability of prime number is very high).
Class M_dh{public:integer Dh_g,dh_p,dh_x,dh_e;integer Dh_y,dh_f;integer dh_k;void set_g_and_p (const Integer G,const Integer p) {dh_g=g;dh_p=p;} void set_y (Integer y) {dh_y=y;} void Set_f (Integer f) {dh_f=f;} void Comp_e (); Integer get_e () {return dh_e;} void Comp_k (); Integer Get_k () {return dh_k;}};
void M_dh::comp_e () {Dh_x=mkrandomnum (+1;dh_e=fastpower_comp) (dh_g,dh_x,dh_p);} void M_dh::comp_k () {dh_k=fastpower_comp (dh_f,dh_x,dh_p);}
2. RSA:
This is about the bare RSA algorithm.
The server generates two different prime numbers p and Q, calculates the modulo n=p*q, and computes the Euler function φ (n) = (p-1) (q-1). The server then generates a number e between 1 and φ (n) with φ (n) coprime to find another number D to satisfy (e*d)%φ (n)==1.
Now the server has three numbers N, E, D , andne in the combination of RSA's public key , ND is the private key . The server sends the public key to the client. In later encryption decryption, the public key is used for encryption and signature verification, and the private key is used for decryption and signing.
Encrypt the number k: Calculate c= (k^e)%n, C is to decrypt the encrypted data C get K:k= (c^d)%n
The signature is in the opposite way that the server is encrypted with the private key, and the client decrypts it with the public key to verify the decrypted data.
However, Ssh-rsa uses the rsassa-pkcs1-v1_5 scheme Standard, and he also contains some other padding values that need to be considered when actually implemented.
Class M_rsa{public:integer Rsa_e;integer rsa_n;void set_e_and_n (Integer e,integer N) {rsa_e=e;rsa_n=n;} Integer comp_rsa_result (integer num);};i Nteger m_rsa::comp_rsa_result (Integer num) {return fastpower_comp (num,rsa_e,rsa_n);}
3, sha256
Hash Algorithm There is nothing to talk about, the main note sha256 the length of the cipher is 64-bit 16, in the RSA encryption and decryption as well as the calculation of SessionID must pay attention to the length of the problem. The focus is on what values are required to participate in the hash operation in a combination.
I use the Cryptopp hash algorithm directly to achieve:
Class M_sha{public:string ENCODE_SHA1 (String data), string encode_sha256 (String data);}; String m_sha::encode_sha256 (String data) {string hash; SHA256 sha256; Hashfilter Hash_filter (SHA256); Hash_filter. Attach (New Hexencoder (new Stringsink (hash), false)); Hash_filter. Put ((BYTE *) data.c_str (), data.length ()); Hash_filter. Messageend (); return hash; }
Detailed process:
The basic algorithm can see the whole process of Diffie-hellman-group-exchange-sha256 .
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/6C/97/wKioL1VNn02iBSeTAAI75MY2k6w762.jpg "title=" Packet1.png "alt=" Wkiol1vnn02ibsetaai75my2k6w762.jpg "/>
The entire exchange process has 5 packets: 1 in order, DH key exchange init;2, DH key exchange reply;3, DH gex init 4, Dhgex reply 5, new keys
1. DH Key exchange init (30)
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/6C/9C/wKiom1VNoKOQAKchAADzwiKKb68813.jpg "style=" float: none; "title=" Packet2.png "alt=" Wkiom1vnokoqakchaadzwikkb68813.jpg "/>
The client tells the server to start the DH interchange.
2. DH key exchange reply (31)
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/6C/97/wKioL1VNohmjIdBHAAFqficzp28657.jpg "style=" float: none; "title=" Packet3.png "alt=" Wkiol1vnohmjidbhaafqficzp28657.jpg "/>
The server sends the generated p and G to the client.
3. DH Gex Init (32)
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/6C/97/wKioL1VNohqCsgE8AAEmKjwKdCI686.jpg "style=" float: none; "title=" Packet4.png "alt=" Wkiol1vnohqcsge8aaemkjwkdci686.jpg "/>
After the client receives the P and G sent by the server, it calculates the e-return to the client.
4. DH Gex Reply (33)
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/6C/9C/wKiom1VNoKTACrmRAAHn6JiQYeA449.jpg "style=" float: none; "title=" Packet5.png "alt=" Wkiom1vnoktacrmraahn6jiqyea449.jpg "/>
After the server receives E from the client, the secret key value K is computed based on the algorithm. Then use the SHA256 algorithm to encrypt some known information hash to H(which is mentioned later in the process) and sign the hash value with RSA. Finally send RSA's public key, DH's F value, RSA signed hash information sent back to the client.
5. New Keys (21)
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/6C/97/wKioL1VNohqx5LDbAADMhK9tZOw927.jpg "style=" float: none; "title=" Packet6.png "alt=" Wkiol1vnohqx5ldbaadmhk9tzow927.jpg "/>
The client calculates the same K value according to the F that the server sends back, and calculates the hash value of the RSA public key Check server sent by the server using the same existing information hash, according to the obtained hash value H , which is the session session_id, then perform a specific hash operation (see below) to get the secret key for data encryption later. If the checksum is correct, a new key (21) is returned, indicating that the key exchange process is complete and that future data will be encrypted by the resulting secret key.
H and session_id calculation:
H=hash (v_c| | v_s| | i_c| | i_s| | k_s| | e| | f| | K);
Values used sequentially (note type):
Type |
Value |
Description |
String |
V_c |
Initial message for the client (version information: ssh-2.0-xxx, excluding the end of CR and LF) |
String |
v_s |
Initial message of the server
|
String |
I_c |
Payload of client Ssh_msg_kex_init (two values without beginning data length and padding length) |
String |
i_s |
Server Ibid. |
String |
k_s |
Host key (DH Gex reply (33) Process server sends host key (RSA public Key)) |
Mpint
|
E |
Client DH Public Key |
Mpint |
F |
Server DH Public Key |
Mpint |
K |
Common DH Calculation results |
The above contents are stitched in order, do not mix or trailing extra characters. The stitched string is sha256 to calculate the result H. This h is the session_id(the first time the session of the secret key exchange generated by the H is session_id, later if the secret key exchange, session_id will not change).
Cryptographic key calculation:
The encryption key here refers to the secret key used in later data communication, generally with the AES algorithm.
Calculation method: Hash (k,h, single character, session_id);
A single character refers to a single uppercase ASCII letter, which is calculated according to the different encryption keys chosen by different characters.
Letters |
Secret key |
A |
Client-to-server initial IV
|
B |
Server-to-client Initial IV |
C |
Client-to-server encryption key (data encryption key) |
D |
Server-to-client encryption keys |
E |
Client-to-server integrity secret key (HMAC) |
F |
Server-to-client integrity secret key |
The SSH key exchange process is over. The author can not find the appropriate information on the Internet, especially these about the Diffie-hellman-group-exchange-sha of many details, their own bitter force for a long time (originally intended to two to learn the other) finally finished. Want to give help to friends who want to implement the algorithm themselves. If you also encounter other problems can Q me (wchrt).
This article is from the "Wchrt" blog, make sure to keep this source http://wchrt.blog.51cto.com/8472636/1649839
SSH key exchange detailed and implementation Diffie-hellman-group-exchange-sha