public class KnownHosts
extends java.lang.Object
KnownHosts
class is a handy tool to verify received server hostkeys
based on the information in known_hosts
files (the ones used by OpenSSH).
It offers basically an in-memory database for known_hosts entries, as well as some
helper functions. Entries from a
It is a thread safe implementation, therefore, you need only to instantiate one
known_hosts
file can be loaded at construction time.
It is also possible to add more keys later (e.g., one can parse different
known_hosts
files).
KnownHosts
for your whole application.
Modifier and Type | Class and Description |
---|---|
private class |
KnownHosts.KnownHostsEntry |
Modifier and Type | Field and Description |
---|---|
static int |
HOSTKEY_HAS_CHANGED |
static int |
HOSTKEY_IS_NEW |
static int |
HOSTKEY_IS_OK |
private static Logger |
LOGGER |
private java.util.LinkedList |
publicKeys |
private static java.security.SecureRandom |
SECURE_RANDOM |
Constructor and Description |
---|
KnownHosts() |
KnownHosts(char[] knownHostsData) |
KnownHosts(java.io.File knownHosts) |
Modifier and Type | Method and Description |
---|---|
void |
addHostkey(java.lang.String[] hostnames,
java.lang.String serverHostKeyAlgorithm,
byte[] serverHostKey)
Adds a single public key entry to the database.
|
void |
addHostkeys(char[] knownHostsData)
Parses the given known_hosts data and adds entries to the database.
|
void |
addHostkeys(java.io.File knownHosts)
Parses the given known_hosts file and adds entries to the database.
|
static void |
addHostkeyToFile(java.io.File knownHosts,
java.lang.String[] hostnames,
java.lang.String serverHostKeyAlgorithm,
byte[] serverHostKey)
Adds a single public key entry to the a known_hosts file.
|
private boolean |
checkHashed(java.lang.String entry,
java.lang.String hostname) |
private int |
checkKey(java.lang.String remoteHostname,
java.lang.Object remoteKey) |
static java.lang.String |
createBubblebabbleFingerprint(java.lang.String keytype,
byte[] publickey)
Convert a ssh2 key-blob into a human readable bubblebabble fingerprint.
|
static java.lang.String |
createHashedHostname(java.lang.String hostname)
Generate the hashed representation of the given hostname.
|
static java.lang.String |
createHexFingerprint(java.lang.String keytype,
byte[] publickey)
Convert a ssh2 key-blob into a human readable hex fingerprint.
|
private java.util.Vector |
getAllKeys(java.lang.String hostname) |
java.lang.String[] |
getPreferredServerHostkeyAlgorithmOrder(java.lang.String hostname)
Try to find the preferred order of hostkey algorithms for the given hostname.
|
private static byte[] |
hmacSha1Hash(byte[] salt,
java.lang.String hostname) |
private boolean |
hostnameMatches(java.lang.String[] hostpatterns,
java.lang.String hostname) |
private void |
initialize(char[] knownHostsData) |
private void |
initialize(java.io.File knownHosts) |
private boolean |
matchKeys(java.lang.Object key1,
java.lang.Object key2) |
private boolean |
pseudoRegex(char[] pattern,
int i,
char[] match,
int j) |
private static byte[] |
rawFingerPrint(java.lang.String type,
java.lang.String keyType,
byte[] hostkey)
Generates a "raw" fingerprint of a hostkey.
|
private static java.lang.String |
rawToBubblebabbleFingerprint(byte[] raw)
Convert a raw fingerprint to bubblebabble representation.
|
private static java.lang.String |
rawToHexFingerprint(byte[] fingerprint)
Convert a raw fingerprint to hex representation (XX:YY:ZZ...).
|
private java.lang.String[] |
recommendHostkeyAlgorithms(java.lang.String hostname) |
int |
verifyHostkey(java.lang.String hostname,
java.lang.String serverHostKeyAlgorithm,
byte[] serverHostKey)
Checks the internal hostkey database for the given hostkey.
|
private static final Logger LOGGER
public static final int HOSTKEY_IS_OK
public static final int HOSTKEY_IS_NEW
public static final int HOSTKEY_HAS_CHANGED
private static final java.security.SecureRandom SECURE_RANDOM
private java.util.LinkedList publicKeys
public KnownHosts()
public KnownHosts(char[] knownHostsData) throws java.io.IOException
java.io.IOException
public KnownHosts(java.io.File knownHosts) throws java.io.IOException
java.io.IOException
public void addHostkey(java.lang.String[] hostnames, java.lang.String serverHostKeyAlgorithm, byte[] serverHostKey) throws java.io.IOException
addHostkeyToFile()
for that purpose.
This method is designed to be used in a ServerHostKeyVerifier
.hostnames
- a list of hostname patterns - at least one most be specified. Check out the
OpenSSH sshd man page for a description of the pattern matching algorithm.serverHostKeyAlgorithm
- as passed to the ServerHostKeyVerifier
.serverHostKey
- as passed to the ServerHostKeyVerifier
.java.io.IOException
public void addHostkeys(char[] knownHostsData) throws java.io.IOException
knownHostsData
- java.io.IOException
public void addHostkeys(java.io.File knownHosts) throws java.io.IOException
knownHosts
- java.io.IOException
public static final java.lang.String createHashedHostname(java.lang.String hostname)
hostname
- private static final byte[] hmacSha1Hash(byte[] salt, java.lang.String hostname)
private final boolean checkHashed(java.lang.String entry, java.lang.String hostname)
private int checkKey(java.lang.String remoteHostname, java.lang.Object remoteKey)
private java.util.Vector getAllKeys(java.lang.String hostname)
public java.lang.String[] getPreferredServerHostkeyAlgorithmOrder(java.lang.String hostname)
ssh-rsa
or ssh-dss
)
an ordered list of hostkey algorithms is returned which can be passed
to Connection.setServerHostKeyAlgorithms
.hostname
- null
if no key for the given hostname is present or
there are keys of multiple types present for the given hostname. Otherwise,
an array with hostkey algorithms is returned (i.e., an array of length 2).private final boolean hostnameMatches(java.lang.String[] hostpatterns, java.lang.String hostname)
private void initialize(char[] knownHostsData) throws java.io.IOException
java.io.IOException
private void initialize(java.io.File knownHosts) throws java.io.IOException
java.io.IOException
private final boolean matchKeys(java.lang.Object key1, java.lang.Object key2)
private final boolean pseudoRegex(char[] pattern, int i, char[] match, int j)
private java.lang.String[] recommendHostkeyAlgorithms(java.lang.String hostname)
public int verifyHostkey(java.lang.String hostname, java.lang.String serverHostKeyAlgorithm, byte[] serverHostKey) throws java.io.IOException
hostname
- the server's hostname, will be matched with all hostname patternsserverHostKeyAlgorithm
- type of hostkey, either ssh-rsa
or ssh-dss
serverHostKey
- the key blobHOSTKEY_IS_OK
: the given hostkey matches an entry for the given hostnameHOSTKEY_IS_NEW
: no entries found for this hostname and this type of hostkeyHOSTKEY_HAS_CHANGED
: hostname is known, but with another key of the same type
(man-in-the-middle attack?)java.io.IOException
- if the supplied key blob cannot be parsed or does not match the given hostkey type.public static final void addHostkeyToFile(java.io.File knownHosts, java.lang.String[] hostnames, java.lang.String serverHostKeyAlgorithm, byte[] serverHostKey) throws java.io.IOException
ServerHostKeyVerifier
.knownHosts
- the file where the publickey entry will be appended.hostnames
- a list of hostname patterns - at least one most be specified. Check out the
OpenSSH sshd man page for a description of the pattern matching algorithm.serverHostKeyAlgorithm
- as passed to the ServerHostKeyVerifier
.serverHostKey
- as passed to the ServerHostKeyVerifier
.java.io.IOException
private static final byte[] rawFingerPrint(java.lang.String type, java.lang.String keyType, byte[] hostkey)
type
- either "md5" or "sha1"keyType
- either "ssh-rsa" or "ssh-dss"hostkey
- the hostkeyprivate static final java.lang.String rawToHexFingerprint(byte[] fingerprint)
fingerprint
- raw fingerprintprivate static final java.lang.String rawToBubblebabbleFingerprint(byte[] raw)
raw
- raw fingerprintpublic static final java.lang.String createHexFingerprint(java.lang.String keytype, byte[] publickey)
Example fingerprint: d0:cb:76:19:99:5a:03:fc:73:10:70:93:f2:44:63:47.
keytype
- either "ssh-rsa" or "ssh-dss"publickey
- key blobpublic static final java.lang.String createBubblebabbleFingerprint(java.lang.String keytype, byte[] publickey)
Example fingerprint: xofoc-bubuz-cazin-zufyl-pivuk-biduk-tacib-pybur-gonar-hotat-lyxux.
keytype
- either "ssh-rsa" or "ssh-dss"publickey
- key data