All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sshtools.common.ssh.components.DiffieHellmanGroups Maven / Gradle / Ivy

/**
 * (c) 2002-2021 JADAPTIVE Limited. All Rights Reserved.
 *
 * This file is part of the Maverick Synergy Java SSH API.
 *
 * Maverick Synergy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Maverick Synergy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Maverick Synergy.  If not, see .
 */
package com.sshtools.common.ssh.components;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import com.sshtools.common.logger.Log;

import com.sshtools.common.util.UnsignedInteger32;

public class DiffieHellmanGroups {

	static final BigInteger TWO = new BigInteger("2");
	
	public static final BigInteger group1 = new BigInteger(
			"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
					+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
					+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
					+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
					+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
					+ "FFFFFFFFFFFFFFFF", 16);

	public static final BigInteger group5 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA237327"
			+ "FFFFFFFF" + "FFFFFFFF", 16);

	public static final BigInteger group14 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA18217C"
			+ "32905E46" + "2E36CE3B" + "E39E772C" + "180E8603" + "9B2783A2"
			+ "EC07A28F" + "B5C55DF0" + "6F4C52C9" + "DE2BCBF6" + "95581718"
			+ "3995497C" + "EA956AE5" + "15D22618" + "98FA0510" + "15728E5A"
			+ "8AACAA68" + "FFFFFFFF" + "FFFFFFFF", 16);

	public static final BigInteger group15 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA18217C"
			+ "32905E46" + "2E36CE3B" + "E39E772C" + "180E8603" + "9B2783A2"
			+ "EC07A28F" + "B5C55DF0" + "6F4C52C9" + "DE2BCBF6" + "95581718"
			+ "3995497C" + "EA956AE5" + "15D22618" + "98FA0510" + "15728E5A"
			+ "8AAAC42D" + "AD33170D" + "04507A33" + "A85521AB" + "DF1CBA64"
			+ "ECFB8504" + "58DBEF0A" + "8AEA7157" + "5D060C7D" + "B3970F85"
			+ "A6E1E4C7" + "ABF5AE8C" + "DB0933D7" + "1E8C94E0" + "4A25619D"
			+ "CEE3D226" + "1AD2EE6B" + "F12FFA06" + "D98A0864" + "D8760273"
			+ "3EC86A64" + "521F2B18" + "177B200C" + "BBE11757" + "7A615D6C"
			+ "770988C0" + "BAD946E2" + "08E24FA0" + "74E5AB31" + "43DB5BFC"
			+ "E0FD108E" + "4B82D120" + "A93AD2CA" + "FFFFFFFF" + "FFFFFFFF",
			16);

	public static final BigInteger group16 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA18217C"
			+ "32905E46" + "2E36CE3B" + "E39E772C" + "180E8603" + "9B2783A2"
			+ "EC07A28F" + "B5C55DF0" + "6F4C52C9" + "DE2BCBF6" + "95581718"
			+ "3995497C" + "EA956AE5" + "15D22618" + "98FA0510" + "15728E5A"
			+ "8AAAC42D" + "AD33170D" + "04507A33" + "A85521AB" + "DF1CBA64"
			+ "ECFB8504" + "58DBEF0A" + "8AEA7157" + "5D060C7D" + "B3970F85"
			+ "A6E1E4C7" + "ABF5AE8C" + "DB0933D7" + "1E8C94E0" + "4A25619D"
			+ "CEE3D226" + "1AD2EE6B" + "F12FFA06" + "D98A0864" + "D8760273"
			+ "3EC86A64" + "521F2B18" + "177B200C" + "BBE11757" + "7A615D6C"
			+ "770988C0" + "BAD946E2" + "08E24FA0" + "74E5AB31" + "43DB5BFC"
			+ "E0FD108E" + "4B82D120" + "A9210801" + "1A723C12" + "A787E6D7"
			+ "88719A10" + "BDBA5B26" + "99C32718" + "6AF4E23C" + "1A946834"
			+ "B6150BDA" + "2583E9CA" + "2AD44CE8" + "DBBBC2DB" + "04DE8EF9"
			+ "2E8EFC14" + "1FBECAA6" + "287C5947" + "4E6BC05D" + "99B2964F"
			+ "A090C3A2" + "233BA186" + "515BE7ED" + "1F612970" + "CEE2D7AF"
			+ "B81BDD76" + "2170481C" + "D0069127" + "D5B05AA9" + "93B4EA98"
			+ "8D8FDDC1" + "86FFB7DC" + "90A6C08F" + "4DF435C9" + "34063199"
			+ "FFFFFFFF" + "FFFFFFFF",
			16);

	public static final BigInteger group17 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA18217C"
			+ "32905E46" + "2E36CE3B" + "E39E772C" + "180E8603" + "9B2783A2"
			+ "EC07A28F" + "B5C55DF0" + "6F4C52C9" + "DE2BCBF6" + "95581718"
			+ "3995497C" + "EA956AE5" + "15D22618" + "98FA0510" + "15728E5A"
			+ "8AAAC42D" + "AD33170D" + "04507A33" + "A85521AB" + "DF1CBA64"
			+ "ECFB8504" + "58DBEF0A" + "8AEA7157" + "5D060C7D" + "B3970F85"
			+ "A6E1E4C7" + "ABF5AE8C" + "DB0933D7" + "1E8C94E0" + "4A25619D"
			+ "CEE3D226" + "1AD2EE6B" + "F12FFA06" + "D98A0864" + "D8760273"
			+ "3EC86A64" + "521F2B18" + "177B200C" + "BBE11757" + "7A615D6C"
			+ "770988C0" + "BAD946E2" + "08E24FA0" + "74E5AB31" + "43DB5BFC"
			+ "E0FD108E" + "4B82D120" + "A9210801" + "1A723C12" + "A787E6D7"
			+ "88719A10" + "BDBA5B26" + "99C32718" + "6AF4E23C" + "1A946834"
			+ "B6150BDA" + "2583E9CA" + "2AD44CE8" + "DBBBC2DB" + "04DE8EF9"
			+ "2E8EFC14" + "1FBECAA6" + "287C5947" + "4E6BC05D" + "99B2964F"
			+ "A090C3A2" + "233BA186" + "515BE7ED" + "1F612970" + "CEE2D7AF"
			+ "B81BDD76" + "2170481C" + "D0069127" + "D5B05AA9" + "93B4EA98"
			+ "8D8FDDC1" + "86FFB7DC" + "90A6C08F" + "4DF435C9" + "34028492"
			+ "36C3FAB4" + "D27C7026" + "C1D4DCB2" + "602646DE" + "C9751E76"
			+ "3DBA37BD" + "F8FF9406" + "AD9E530E" + "E5DB382F" + "413001AE"
			+ "B06A53ED" + "9027D831" + "179727B0" + "865A8918" + "DA3EDBEB"
			+ "CF9B14ED" + "44CE6CBA" + "CED4BB1B" + "DB7F1447" + "E6CC254B"
			+ "33205151" + "2BD7AF42" + "6FB8F401" + "378CD2BF" + "5983CA01"
			+ "C64B92EC" + "F032EA15" + "D1721D03" + "F482D7CE" + "6E74FEF6"
			+ "D55E702F" + "46980C82" + "B5A84031" + "900B1C9E" + "59E7C97F"
			+ "BEC7E8F3" + "23A97A7E" + "36CC88BE" + "0F1D45B7" + "FF585AC5"
			+ "4BD407B2" + "2B4154AA" + "CC8F6D7E" + "BF48E1D8" + "14CC5ED2"
			+ "0F8037E0" + "A79715EE" + "F29BE328" + "06A1D58B" + "B7C5DA76"
			+ "F550AA3D" + "8A1FBFF0" + "EB19CCB1" + "A313D55C" + "DA56C9EC"
			+ "2EF29632" + "387FE8D7" + "6E3C0468" + "043E8F66" + "3F4860EE"
			+ "12BF2D5B" + "0B7474D6" + "E694F91E" + "6DCC4024" + "FFFFFFFF"
			+ "FFFFFFFF", 16);

	public static final BigInteger group18 = new BigInteger("FFFFFFFF"
			+ "FFFFFFFF" + "C90FDAA2" + "2168C234" + "C4C6628B" + "80DC1CD1"
			+ "29024E08" + "8A67CC74" + "020BBEA6" + "3B139B22" + "514A0879"
			+ "8E3404DD" + "EF9519B3" + "CD3A431B" + "302B0A6D" + "F25F1437"
			+ "4FE1356D" + "6D51C245" + "E485B576" + "625E7EC6" + "F44C42E9"
			+ "A637ED6B" + "0BFF5CB6" + "F406B7ED" + "EE386BFB" + "5A899FA5"
			+ "AE9F2411" + "7C4B1FE6" + "49286651" + "ECE45B3D" + "C2007CB8"
			+ "A163BF05" + "98DA4836" + "1C55D39A" + "69163FA8" + "FD24CF5F"
			+ "83655D23" + "DCA3AD96" + "1C62F356" + "208552BB" + "9ED52907"
			+ "7096966D" + "670C354E" + "4ABC9804" + "F1746C08" + "CA18217C"
			+ "32905E46" + "2E36CE3B" + "E39E772C" + "180E8603" + "9B2783A2"
			+ "EC07A28F" + "B5C55DF0" + "6F4C52C9" + "DE2BCBF6" + "95581718"
			+ "3995497C" + "EA956AE5" + "15D22618" + "98FA0510" + "15728E5A"
			+ "8AAAC42D" + "AD33170D" + "04507A33" + "A85521AB" + "DF1CBA64"
			+ "ECFB8504" + "58DBEF0A" + "8AEA7157" + "5D060C7D" + "B3970F85"
			+ "A6E1E4C7" + "ABF5AE8C" + "DB0933D7" + "1E8C94E0" + "4A25619D"
			+ "CEE3D226" + "1AD2EE6B" + "F12FFA06" + "D98A0864" + "D8760273"
			+ "3EC86A64" + "521F2B18" + "177B200C" + "BBE11757" + "7A615D6C"
			+ "770988C0" + "BAD946E2" + "08E24FA0" + "74E5AB31" + "43DB5BFC"
			+ "E0FD108E" + "4B82D120" + "A9210801" + "1A723C12" + "A787E6D7"
			+ "88719A10" + "BDBA5B26" + "99C32718" + "6AF4E23C" + "1A946834"
			+ "B6150BDA" + "2583E9CA" + "2AD44CE8" + "DBBBC2DB" + "04DE8EF9"
			+ "2E8EFC14" + "1FBECAA6" + "287C5947" + "4E6BC05D" + "99B2964F"
			+ "A090C3A2" + "233BA186" + "515BE7ED" + "1F612970" + "CEE2D7AF"
			+ "B81BDD76" + "2170481C" + "D0069127" + "D5B05AA9" + "93B4EA98"
			+ "8D8FDDC1" + "86FFB7DC" + "90A6C08F" + "4DF435C9" + "34028492"
			+ "36C3FAB4" + "D27C7026" + "C1D4DCB2" + "602646DE" + "C9751E76"
			+ "3DBA37BD" + "F8FF9406" + "AD9E530E" + "E5DB382F" + "413001AE"
			+ "B06A53ED" + "9027D831" + "179727B0" + "865A8918" + "DA3EDBEB"
			+ "CF9B14ED" + "44CE6CBA" + "CED4BB1B" + "DB7F1447" + "E6CC254B"
			+ "33205151" + "2BD7AF42" + "6FB8F401" + "378CD2BF" + "5983CA01"
			+ "C64B92EC" + "F032EA15" + "D1721D03" + "F482D7CE" + "6E74FEF6"
			+ "D55E702F" + "46980C82" + "B5A84031" + "900B1C9E" + "59E7C97F"
			+ "BEC7E8F3" + "23A97A7E" + "36CC88BE" + "0F1D45B7" + "FF585AC5"
			+ "4BD407B2" + "2B4154AA" + "CC8F6D7E" + "BF48E1D8" + "14CC5ED2"
			+ "0F8037E0" + "A79715EE" + "F29BE328" + "06A1D58B" + "B7C5DA76"
			+ "F550AA3D" + "8A1FBFF0" + "EB19CCB1" + "A313D55C" + "DA56C9EC"
			+ "2EF29632" + "387FE8D7" + "6E3C0468" + "043E8F66" + "3F4860EE"
			+ "12BF2D5B" + "0B7474D6" + "E694F91E" + "6DBE1159" + "74A3926F"
			+ "12FEE5E4" + "38777CB6" + "A932DF8C" + "D8BEC4D0" + "73B931BA"
			+ "3BC832B6" + "8D9DD300" + "741FA7BF" + "8AFC47ED" + "2576F693"
			+ "6BA42466" + "3AAB639C" + "5AE4F568" + "3423B474" + "2BF1C978"
			+ "238F16CB" + "E39D652D" + "E3FDB8BE" + "FC848AD9" + "22222E04"
			+ "A4037C07" + "13EB57A8" + "1A23F0C7" + "3473FC64" + "6CEA306B"
			+ "4BCBC886" + "2F8385DD" + "FA9D4B7F" + "A2C087E8" + "79683303"
			+ "ED5BDD3A" + "062B3CF5" + "B3A278A6" + "6D2A13F8" + "3F44F82D"
			+ "DF310EE0" + "74AB6A36" + "4597E899" + "A0255DC1" + "64F31CC5"
			+ "0846851D" + "F9AB4819" + "5DED7EA1" + "B1D510BD" + "7EE74D73"
			+ "FAF36BC3" + "1ECFA268" + "359046F4" + "EB879F92" + "4009438B"
			+ "481C6CD7" + "889A002E" + "D5EE382B" + "C9190DA6" + "FC026E47"
			+ "9558E447" + "5677E9AA" + "9E3050E2" + "765694DF" + "C81F56E8"
			+ "80B96E71" + "60C980DD" + "98EDD3DF" + "FFFFFFFF" + "FFFFFFFF",
			16);

	static List safePrimes = new ArrayList();
	static List customPrimes = new ArrayList();
	
	static {
		safePrimes.add(group1);
		safePrimes.add(group5);
		safePrimes.add(group14);
		safePrimes.add(group15);
		safePrimes.add(group16);
		safePrimes.add(group17);
		safePrimes.add(group18);
	}
	
	public static class DHGroup {
		
		BigInteger g;
		BigInteger p;
		Integer size;
		
		private DHGroup(Integer size, BigInteger g, BigInteger p) {
			this.size = size;
			this.g= g;
			this.p = p;
		}

		public BigInteger getG() {
			return g;
		}

		public BigInteger getP() {
			return p;
		}

		public Integer getSize() {
			return size;
		}
		
	}
	
	public static final int TYPE_SAFE = 2;
	public static final int TESTS_COMPOSITE = 0x01;
	
	public static void loadGroups(URI url) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(url.toURL().openStream()));
		String line;
		while((line = reader.readLine())!=null) {
			line = line.trim();
			if(line.startsWith("#")) {
				continue;
			}
			String[] parts = line.split("\\s+");
			if(parts.length != 7) {
				continue;
			}
			Integer t = Integer.parseInt(parts[1]);
			if(t != 2) {
				continue;
			}
			t = Integer.parseInt(parts[2]);
			if((t & TESTS_COMPOSITE) != 0 || (t & ~TESTS_COMPOSITE) == 0) {
				continue;
			}
			if(Integer.parseInt(parts[3]) == 0) {
				continue;
			}
			customPrimes.add(new DHGroup(Integer.parseInt(parts[4]) + 1,
					new BigInteger(parts[5], 16),
					new BigInteger(parts[6], 16)));
			
		}
		
		Collections.sort(customPrimes, new Comparator() {
			@Override
			public int compare(DHGroup o1, DHGroup o2) {
				return o1.size.compareTo(o2.getSize());
			}
		});
	}
	
	public static boolean verifyParameters(BigInteger shared, BigInteger p) {
		
		if(shared.compareTo(BigInteger.ONE) <= 0 
				|| shared.compareTo(p.subtract(BigInteger.ONE)) >= 0) { 
			Log.error("Invalid DH shared value (1 < y < p-1) {}", shared.toString(16));
			return false;
		}
		return true;
	}
		
	/**
	 * get the biggest safe prime from the list that is <= maximumSize
	 * @param maximumSize
	 * @return BigInteger
	 */
	public static DHGroup getSafePrime(UnsignedInteger32 maximumSize) {

		if(Log.isDebugEnabled()) {
			Log.debug("Looking for diffie hellman group with maximum size of " + maximumSize.intValue() + " bits");
		}
		
		List selectedGroups = new ArrayList();
		int largedSize = 0;
		for(DHGroup group : customPrimes) {
			if(group.getSize() > maximumSize.intValue()) {
				break;
			}
			if(largedSize < group.getSize()) {
				largedSize = group.getSize();
				selectedGroups.clear();
			}
			selectedGroups.add(group);
		}
		
		if(!selectedGroups.isEmpty()) {
			return selectedGroups.get(new Random().nextInt(selectedGroups.size()));
		}
		
		BigInteger prime = group1;
		for(Iterator it = safePrimes.iterator(); it.hasNext(); ) {
			BigInteger p = it.next();
			int len = p.bitLength();
			if(len > maximumSize.intValue()) {
				break;
			}
			prime = p;
		}
		
		if(Log.isDebugEnabled()) {
			Log.debug("Found diffie hellman group with " + prime.bitLength() + " bits");
		}
		return new DHGroup(prime.bitLength(), TWO, prime);
	}

	public static Collection allDefaultGroups() {
		return Collections.unmodifiableList(safePrimes);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy