Please note that all text insire quotes in the EBNF here is to be taken to mean bytes that would decode as that using the ASCII. character encoding. "\n" refers specifically to the byte 0x0a, and no alternative newlines are acceptable. The file has a header like: magic = "SSHWOT" ; version = "0" ; comment = ? General comment about the file. Valid utf-8, no '\n'. ? ; header = magic, " ", version, [" ", comment], "\n" ; Examples of valid headers would be "SSHWOT 0\n" and "SSHWOT 0 Emma G. 2018\n". "SSHWOT 0 \n" is not valid, since a space marks that there will be a comment. After the header the entries are laid out as: salt = ? base64(salt) ? ; hashed host = ? base64(sha256(host concat salt)) ? ; fingerprint = ? base64(sha256-fingerprint) ? ; comment = ? Comment about the host/key. Valid utf-8, no '\n'. ? ; entry = salt, " ", hashed host, " ", fingerprint, [" ", comment], "\n" ; The version of base64 used uses + for 62 and / for 63, doesn't use = for padding, and contains no breaks. Examples of valid entries are "Yixx+B6zrFoubPhBddgyx0nXHmbqMW1Wzneo4JqJv0U yPUACFC/zPt/ENoIluOuWiTXor3r7oHhac63qej637E QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2A\n" and "bd/MfFs+DMVqNQQoZGGCvpTopeS0/Jt6GS5vg7J+638 cbbdTnuIh0ZwnM+/r3sAu4iHgaN3mpkcP9kJND4vBUo YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4A The old one\n" Again, if there is a space following the necessary parts, there must also be a comment or else the entry is malformed. If port is not 22, the host is [domain]:port. This is in accordance with how OpenSSH stores it in .ssh/known_hosts. Internationalized domain names are punycoded and all domain names are converted into lower case. This differs from OpenSSH, which is not IDN-aware. Sha256 is used instead of a password hash since we want checking for whether a host is present to be reasonably fast.