pubkeyfmt.but 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. \A{ppk} PPK file format
  2. This appendix documents the file format used by PuTTY to store private
  3. keys.
  4. In this appendix, binary data structures are described using data type
  5. representations such as \cq{uint32}, \cq{string} and \cq{mpint} as
  6. used in the SSH protocol standards themselves. These are defined
  7. authoritatively by
  8. \W{https://www.rfc-editor.org/rfc/rfc4251#section-5}{RFC 4251 section 5},
  9. \q{Data Type Representations Used in the SSH Protocols}.
  10. \H{ppk-overview} Overview
  11. A PPK file stores a private key, and the corresponding public key.
  12. Both are contained in the same file.
  13. The file format can be completely unencrypted, or it can encrypt the
  14. private key. The \e{public} key is stored in cleartext in both cases.
  15. (This enables PuTTY to send the public key to an SSH server to see
  16. whether it will accept it, and not bother prompting for the passphrase
  17. unless the server says yes.)
  18. When the key file is encrypted, the encryption key is derived from a
  19. passphrase. An encrypted PPK file is also tamper-proofed using a MAC
  20. (authentication code), also derived from the same passphrase. The MAC
  21. protects the encrypted private key data, but it also covers the
  22. cleartext parts of the file. So you can't edit the public half of the
  23. key without invalidating the MAC and causing the key file as a whole
  24. to become useless.
  25. This MAC protects the key file against active cryptographic attacks in
  26. which the public half of a key pair is modified in a controlled way
  27. that allows an attacker to deduce information about the private half
  28. from the resulting corrupted signatures. Any attempt to do that to a
  29. PPK file should be reliably caught by the MAC failing to validate.
  30. (Such an attack would only be useful if the key file was stored in a
  31. location where the attacker could modify it without also having full
  32. access to the process that you type passphrases into. But that's not
  33. impossible; for example, if your home directory was on a network file
  34. server, then the file server's administrator could access the key file
  35. but not processes on the client machine.)
  36. The MAC also covers the \e{comment} on the key. This stops an attacker
  37. from swapping keys with each other and editing the comments to
  38. disguise the fact. As a consequence, PuTTYgen cannot edit the comment
  39. on a key unless you decrypt the key with your passphrase first.
  40. (The circumstances in which \e{that} attack would be useful are even
  41. more restricted. One example might be that the different keys trigger
  42. specific actions on the server you're connecting to and one of those
  43. actions is more useful to the attacker than the other. But once you
  44. have a MAC at all, it's no extra effort to make it cover as much as
  45. possible, and usually sensible.)
  46. \H{ppk-outer} Outer layer
  47. The outer layer of a PPK file is text-based. The PuTTY tools will
  48. always use LF line termination when writing PPK files, but will
  49. tolerate CR+LF and CR-only on input.
  50. The first few lines identify it as a PPK, and give some initial data
  51. about what's stored in it and how. They look like this:
  52. \c PuTTY-User-Key-File-version: algorithm-name
  53. \e bbbbbbb bbbbbbbbbbbbbb
  54. \c Encryption: encryption-type
  55. \e bbbbbbbbbbbbbbb
  56. \c Comment: key-comment-string
  57. \e bbbbbbbbbbbbbbbbbb
  58. \s{version} is a decimal number giving the version number of the file
  59. format itself. The current file format version is 3.
  60. \s{algorithm-name} is the SSH protocol identifier for the public key
  61. algorithm that this key is used for (such as \cq{ssh-dss} or
  62. \cq{ecdsa-sha2-nistp384}).
  63. \s{encryption-type} indicates whether this key is stored encrypted,
  64. and if so, by what method. Currently the only supported encryption
  65. types are \cq{aes256-cbc} and \cq{none}.
  66. \s{key-comment-string} is a free text field giving the comment. This
  67. can contain any byte values other than 13 and 10 (CR and LF).
  68. The next part of the file gives the public key. This is stored
  69. unencrypted but base64-encoded
  70. (\W{https://www.rfc-editor.org/rfc/rfc4648}{RFC 4648}), and is preceded
  71. by a header line saying how many lines of base64 data are shown,
  72. looking like this:
  73. \c Public-Lines: number-of-lines
  74. \e bbbbbbbbbbbbbbb
  75. \c that many lines of base64 data
  76. \e bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  77. The base64-encoded data in this blob is formatted in exactly the same
  78. way as an SSH public key sent over the wire in the SSH protocol
  79. itself. That is also the same format as the base64 data stored in
  80. OpenSSH's \c{authorized_keys} file, except that in a PPK file the
  81. base64 data is split across multiple lines. But if you remove the
  82. newlines from the middle of this section, the resulting base64 blob is
  83. in the right format to go in an \c{authorized_keys} line.
  84. If the key is encrypted (i.e. \s{encryption-type} is not \cq{none}),
  85. then the next thing that appears is a sequence of lines specifying how
  86. the keys for encrypting the file are to be derived from the
  87. passphrase:
  88. \c Key-Derivation: argon2-flavour
  89. \e bbbbbbbbbbbbbb
  90. \c Argon2-Memory: decimal-integer
  91. \e bbbbbbbbbbbbbbb
  92. \c Argon2-Passes: decimal-integer
  93. \e bbbbbbbbbbbbbbb
  94. \c Argon2-Parallelism: decimal-integer
  95. \e bbbbbbbbbbbbbbb
  96. \c Argon2-Salt: hex-string
  97. \e bbbbbbbbbb
  98. \s{argon2-flavour} is one of the identifiers \cq{Argon2d},
  99. \cq{Argon2i} or \cq{Argon2id}, all describing variants of the Argon2
  100. password-hashing function.
  101. The three integer values are used as parameters for Argon2, which
  102. allows you to configure the amount of memory used (in Kbyte), the number
  103. of passes of the algorithm to run (to tune its running time), and the
  104. degree of parallelism required by the hash function. The salt is
  105. decoded into a sequence of binary bytes and used as an additional
  106. input to Argon2. (It is chosen randomly when the key file is written,
  107. so that a guessing attack can't be mounted in parallel against
  108. multiple key files.)
  109. The next part of the file gives the private key. This is
  110. base64-encoded in the same way:
  111. \c Private-Lines: number-of-lines
  112. \e bbbbbbbbbbbbbbb
  113. \c that many lines of base64 data
  114. \e bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  115. The binary data represented in this base64 blob may be encrypted,
  116. depending on the \e{encryption-type} field in the key file header
  117. shown above:
  118. \b If \s{encryption-type} is \cq{none}, then this data is stored in
  119. plain text.
  120. \b If \s{encryption-type} is \cq{aes256-cbc}, then this data is
  121. encrypted using AES, with a 256-bit key length, in the CBC cipher
  122. mode. The key and initialisation vector are derived from the
  123. passphrase: see \k{ppk-keys}.
  124. \lcont{
  125. In order to encrypt the private key data with AES, it must be a
  126. multiple of 16 bytes (the AES cipher block length). This is achieved
  127. by appending random padding to the data before encrypting it. When
  128. decoding it after decryption, the random data can be ignored: the
  129. internal structure of the data is enough to tell you when you've
  130. reached the end of the meaningful part.
  131. }
  132. Unlike public keys, the binary encoding of private keys is not
  133. specified at all in the SSH standards. See \k{ppk-privkeys} for
  134. details of the private key format for each key type supported by
  135. PuTTY.
  136. The final thing in the key file is the MAC:
  137. \c Private-MAC: hex-mac-data
  138. \e bbbbbbbbbbbb
  139. \s{hex-mac-data} is a hexadecimal-encoded value, 64 digits long (i.e.
  140. 32 bytes), generated using the HMAC-SHA-256 algorithm with the
  141. following binary data as input:
  142. \b \cw{string}: the \s{algorithm-name} header field.
  143. \b \cw{string}: the \s{encryption-type} header field.
  144. \b \cw{string}: the \s{key-comment-string} header field.
  145. \b \cw{string}: the binary public key data, as decoded from the base64
  146. lines after the \cq{Public-Lines} header.
  147. \b \cw{string}: the plaintext of the binary private key data, as
  148. decoded from the base64 lines after the \cq{Private-Lines} header. If
  149. that data was stored encrypted, then the decrypted version of it is
  150. used in this MAC preimage, \e{including} the random padding mentioned
  151. above.
  152. The MAC key is derived from the passphrase: see \k{ppk-keys}.
  153. \H{ppk-privkeys} Private key encodings
  154. This section describes the private key format for each key type
  155. supported by PuTTY.
  156. Because the PPK format also contains the public key (and both public
  157. and private key are protected by the same MAC to ensure they can't be
  158. made inconsistent), there is no need for the private key section of
  159. the file to repeat data from the public section. So some of these
  160. formats are very short.
  161. In all cases, a decoding application can begin reading from the start
  162. of the decrypted private key data, and know when it has read all that
  163. it needs. This allows random padding after the meaningful data to be
  164. safely ignored.
  165. \S{ppk-privkey-rsa} RSA
  166. RSA keys are stored using an \s{algorithm-name} of \cq{ssh-rsa}. (Keys
  167. stored like this are also used by the updated RSA signature schemes
  168. that use hashes other than SHA-1.)
  169. The public key data has already provided the key modulus and the
  170. public encoding exponent. The private data stores:
  171. \b \cw{mpint}: the private decoding exponent of the key.
  172. \b \cw{mpint}: one prime factor \e{p} of the key.
  173. \b \cw{mpint}: the other prime factor \e{q} of the key. (RSA keys
  174. stored in this format are expected to have exactly two prime factors.)
  175. \b \cw{mpint}: the multiplicative inverse of \e{q} modulo \e{p}.
  176. \S{ppk-privkey-dsa} DSA
  177. DSA keys are stored using an \s{algorithm-name} of \cq{ssh-dss}.
  178. The public key data has already provided the key parameters (the large
  179. prime \e{p}, the small prime \e{q} and the group generator \e{g}), and
  180. the public key \e{y}. The private key stores:
  181. \b \cw{mpint}: the private key \e{x}, which is the discrete logarithm
  182. of \e{y} in the group generated by \e{g} mod \e{p}.
  183. \S{ppk-privkey-ecdsa} NIST elliptic-curve keys
  184. \i{NIST} elliptic-curve keys are stored using one of the following
  185. \s{algorithm-name} values, each corresponding to a different elliptic
  186. curve and key size:
  187. \b \cq{ecdsa-sha2-nistp256}
  188. \b \cq{ecdsa-sha2-nistp384}
  189. \b \cq{ecdsa-sha2-nistp521}
  190. The public key data has already provided the public elliptic curve
  191. point. The private key stores:
  192. \b \cw{mpint}: the private exponent, which is the discrete log of the
  193. public point.
  194. \S{ppk-privkey-eddsa} EdDSA elliptic-curve keys (Ed25519 and Ed448)
  195. EdDSA elliptic-curve keys are stored using one of the following
  196. \s{algorithm-name} values, each corresponding to a different elliptic
  197. curve and key size:
  198. \b \cq{ssh-ed25519}
  199. \b \cq{ssh-ed448}
  200. The public key data has already provided the public elliptic curve
  201. point. The private key stores:
  202. \b \cw{mpint}: the private exponent, which is the discrete log of the
  203. public point.
  204. \H{ppk-keys} Key derivation
  205. When a key file is encrypted, there are three pieces of key material
  206. that need to be computed from the passphrase:
  207. \b the key for the symmetric cipher used to encrypt the private key
  208. \b the initialisation vector for that cipher encryption
  209. \b the key for the MAC.
  210. If \s{encryption-type} is \cq{aes256-cbc}, then the symmetric cipher
  211. key is 32 bytes long, and the initialisation vector is 16 bytes (one
  212. cipher block). The length of the MAC key is also chosen to be 32
  213. bytes.
  214. If \s{encryption-type} is \cq{none}, then all three of these pieces of
  215. data have zero length. (The MAC is still generated and checked in the
  216. key file format, but it has a zero-length key.)
  217. If the amount of key material required is not zero, then the
  218. passphrase is fed to the Argon2 key derivation function, in whichever
  219. mode is described in the \cq{Key-Derivation} header in the key file,
  220. with parameters derived from the various
  221. \q{\cw{Argon2-}\e{Parameter}\cw{:}} headers.
  222. (If the key is unencrypted, then all those headers are omitted, and
  223. Argon2 is not run at all.)
  224. Argon2 takes two extra string inputs in addition to the passphrase and
  225. the salt: a secret key, and some \q{associated data}. In PPK's use of
  226. Argon2, these are both set to the empty string.
  227. The \q{tag length} parameter to Argon2 (i.e. the amount of data it is
  228. asked to output) is set to the sum of the lengths of all of the data
  229. items required, i.e. (cipher key length + IV length + MAC key length).
  230. The output data is interpreted as the concatenation of the cipher key,
  231. the IV and the MAC key, in that order.
  232. So, for \cq{aes256-cbc}, the tag length will be 32+16+32\_=\_80 bytes;
  233. of the 80 bytes of output data, the first 32 bytes are used as the
  234. 256-bit AES key, the next 16 as the CBC IV, and the final 32 bytes as
  235. the HMAC-SHA-256 key.
  236. \H{ppk-old} Older versions of the PPK format
  237. \S{ppk-v2} Version 2
  238. PPK version 2 was used by PuTTY 0.52 to 0.74 inclusive.
  239. In PPK version 2, the MAC algorithm used was HMAC-SHA-1 (so the
  240. \cw{Private-MAC} line contained only 40 hex digits).
  241. The \cq{Key-Derivation:} header and all the
  242. \q{\cw{Argon2-}\e{Parameter}\cw{:}} headers were absent. Instead of
  243. using Argon2, the key material for encrypting the private blob was
  244. derived from the passphrase in a totally different way, as follows.
  245. The cipher key for \cq{aes256-cbc} was constructed by generating two
  246. SHA-1 hashes, concatenating them, and taking the first 32 bytes of the
  247. result. (So you'd get all 20 bytes of the first hash output, and the
  248. first 12 of the second). Each hash preimage was as follows:
  249. \b \cw{uint32}: a sequence number. This is 0 in the first hash, and 1
  250. in the second. (The idea was to extend this mechanism to further
  251. hashes by continuing to increment the sequence number, if future
  252. changes required even longer keys.)
  253. \b the passphrase, without any prefix length field.
  254. In PPK v2, the CBC initialisation vector was all zeroes.
  255. The MAC key was 20 bytes long, and was a single SHA-1 hash of the
  256. following data:
  257. \b the fixed string \cq{putty-private-key-file-mac-key}, without any
  258. prefix length field.
  259. \b the passphrase, without any prefix length field. (If the key is
  260. stored unencrypted, the passphrase was taken to be the empty string
  261. for these purposes.)
  262. \S{ppk-v1} Version 1
  263. PPK version 1 was a badly designed format, only used during initial
  264. development, and not recommended for production use.
  265. PPK version 1 was never used by a released version of PuTTY. It was
  266. only emitted by some early development snapshots between version 0.51
  267. (which did not support SSH-2 public keys at all) and 0.52 (which
  268. already used version 2 of this file format). I \e{hope} there are no
  269. PPK v1 files in use anywhere. But just in case, the old badly designed
  270. format is documented here anyway.
  271. In PPK version 1, the input to the MAC does not include any of the
  272. header fields or the public key. It is simply the private key data
  273. (still in plaintext and including random padding), all by itself
  274. (without a wrapping \cw{string}).
  275. PPK version 1 keys must therefore be rigorously validated after
  276. loading, to ensure that the public and private parts of the key were
  277. consistent with each other.
  278. PPK version 1 only supported the RSA and DSA key types. For RSA, this
  279. validation can be done using only the provided data (since the private
  280. key blob contains enough information to reconstruct the public values
  281. anyway). But for DSA, that isn't quite enough.
  282. Hence, PPK version 1 DSA keys extended the private data so that
  283. immediately after \e{x} was stored an extra value:
  284. \b \cw{string}: a SHA-1 hash of the public key data, whose preimage
  285. consists of
  286. \lcont{
  287. \b \cw{string}: the large prime \e{p}
  288. \b \cw{string}: the small prime \e{q}
  289. \b \cw{string}: the group generator \e{g}
  290. }
  291. The idea was that checking this hash would verify that the key
  292. parameters had not been tampered with, and then the loading
  293. application could directly verify that
  294. \e{g}\cw{^}\e{x}\cw{\_=\_}\e{y}.
  295. In an \e{unencrypted} version 1 key file, the MAC is replaced by a
  296. plain SHA-1 hash of the private key data. This is indicated by the
  297. \cq{Private-MAC:} header being replaced with \cq{Private-Hash:}
  298. instead.