updating refs, finished key gen buffer

This commit is contained in:
brent s. 2020-09-21 01:43:22 -04:00
parent 382aaffa39
commit b80b823c02
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
15 changed files with 567 additions and 550 deletions

View File

@ -48,6 +48,9 @@ with much stronger implementations from typical/upstream defaults.
It takes the recommendations from _[Secure Secure Shell](https://stribika.github.io/2015/01/04/secure-secure-shell.html)_ (and perhaps other sources) and automatically applies It takes the recommendations from _[Secure Secure Shell](https://stribika.github.io/2015/01/04/secure-secure-shell.html)_ (and perhaps other sources) and automatically applies
them. them.
Additionally, it anonymizes your key. It uses a comment string by default that provides
no identifying information other than the fact that you are using SSHSecure.
It will create backups of any file(s) it replaces and automatically rolls back `sshd` It will create backups of any file(s) it replaces and automatically rolls back `sshd`
configuration changes if it does not pass the syntax check (`sshd -t`) to avoid configuration changes if it does not pass the syntax check (`sshd -t`) to avoid
accidentally locking you out. accidentally locking you out.
@ -63,7 +66,21 @@ running already).
## FAQ ## FAQ


### Why a binary? ### Why a binary?
I originally wrote this as a python script. However, some machines don't have the python interpreter installed and due to the lack of low-level access, I ended up making a lot I originally wrote this as a python script. However, some machines don't have the python
of calls to the shell anyways. interpreter installed and due to the lack of low-level access, I ended up making a lot
of calls to the shell anyways.
I wrote it in Golang so the source would be easily read for audit purposes. I wrote it in Golang so the source would be easily read for auditing purposes.

### How can I contact you?
You can either [file a bug](https://bugs.square-r00t.net/index.php?do=newtask&project=15)
or email me at `bts [at] square-r00t (dot) net`.

### Is there anything from the _Secure Secure Shell_ document that you don't implement?
Yep. No TOR hidden service ("Traffic analysis resistance"). The system should be
sufficiently hardened to prevent you from scans yielding anything useful except noisy
logs, and there's much better options for handling those than running SSH over TOR. It
[isn't the silver bullet you may think it is](https://restoreprivacy.com/tor/). You are,
of course, welcome to turn it up yourself but it is advisable to not run SSHSecure in an
automated fashion in this case as it may revert the changes your `sshd_config`. It'll
try not to, but it may.

1
go.mod
View File

@ -4,5 +4,6 @@ go 1.15


require ( require (
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a
github.com/go-restruct/restruct v1.2.0-alpha
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
) )

15
go.sum
View File

@ -1,5 +1,16 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU= github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0= github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0=
github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=
github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -7,3 +18,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -18,9 +18,15 @@


package sshkeys package sshkeys


import (
`encoding/binary`

`github.com/go-restruct/restruct`
)

// These are just here to save some typing. // These are just here to save some typing.
func getBytelenStr(s string) []byte { func getBytelenStr(s string) []byte {
return getByteInt(len(s)) return getBytelenByteArr([]byte(s))
} }


func getBytelenByteArr(b []byte) []byte { func getBytelenByteArr(b []byte) []byte {
@ -28,5 +34,15 @@ func getBytelenByteArr(b []byte) []byte {
} }


func getByteInt(i int) []byte { func getByteInt(i int) []byte {
return []byte{byte(i)} // This does not work. Despite being a uint32, golang always only writes it as 1 byte instead of 4.
// ...Despite it occupying 4 bytes in RAM.
// Luckily we can reuse this quick one-liner in getSingleByteInt().
// return []byte{byte(i)}
b := make([]byte, 4)
b, _ = restruct.Pack(binary.BigEndian, uint32(i))
return b
} }

func getSingleByteInt(i int) []byte {
return []byte{byte(uint32(i))}
}

57
sshkeys/crypt.go Normal file
View File

@ -0,0 +1,57 @@
package sshkeys

import (
`crypto/aes`
`crypto/cipher`
`errors`

// `golang.org/x/crypto/ssh/internal/bcrypt_pbkdf` Golang doesn't let you import "internal" libs. Fine. Lame language.
`github.com/dchest/bcrypt_pbkdf`
)

func (k *EncryptedSSHKeyV1) setCrypt() error {
// First we need the KDF (Key Derivation Function).
if err := k.setKDF(); err != nil {
return err
}
// And then we set the actual cipher (the thing that does the encrypting).
if err := k.setCipher(); err != nil {
return err
}
return nil
}

func (k *EncryptedSSHKeyV1) setCipher() error {
switch k.CipherName {
case CipherAes256Ctr:
if k.Crypt.Cipher, err = aes.NewCipher(k.Crypt.PrivateKey); err != nil {
return err
} else {
k.Crypt.Stream = cipher.NewCTR(k.Crypt.Cipher, k.Crypt.CryptSalt)
// Can then be used as k.Crypt.Stream.XORKeyStream(dst []byte, src []byte)
}
default:
return errors.New("could not find Cipher")
}
return nil
}

func (k *EncryptedSSHKeyV1) setKDF() error {
// Upstream only currently supports bcrypt_pbkdf ("bcrypt").
// This should always eval to true, but is here for future planning in case other KDF are implemented.
switch k.KDFName {
case KdfBcrypt:
if k.Crypt.CryptKey, err = bcrypt_pbkdf.Key(k.Passphrase,
k.KDFOpts.Salt,
int(k.KDFOpts.Rounds),
kdfKeyLen + len(k.KDFOpts.Salt),
); err != nil {
return err
} else {
k.Crypt.PrivateKey = k.Crypt.CryptKey[0:kdfSplit]
k.Crypt.CryptSalt = k.Crypt.CryptKey[kdfSplit:]
}
default:
return errors.New("could not find KDF")
}
}

View File

@ -19,14 +19,10 @@
package sshkeys package sshkeys


import ( import (
"crypto/aes" `bytes`
"crypto/cipher"
"crypto/rand" "crypto/rand"
"errors" "errors"
"fmt" "fmt"

// `golang.org/x/crypto/ssh/internal/bcrypt_pbkdf` Golang doesn't let you import "internal" libs. Fine. Lame language.
"github.com/dchest/bcrypt_pbkdf"
) )


func (k *EncryptedSSHKeyV1) validate() error { func (k *EncryptedSSHKeyV1) validate() error {
@ -86,7 +82,6 @@ func (k *EncryptedSSHKeyV1) Generate(force bool) error {
} }
if k.DefKeyType == KeyEd25519 { if k.DefKeyType == KeyEd25519 {
k.KeySize = keyEd25519 k.KeySize = keyEd25519
k.BlockSize = blockEd25519
} }
// Currently, OpenSSH has an option for multiple private keys. However, it is hardcoded to 1. // Currently, OpenSSH has an option for multiple private keys. However, it is hardcoded to 1.
// If multiple key support is added in the future, will need to re-tool how I do this, perhaps, in the future. TODO. // If multiple key support is added in the future, will need to re-tool how I do this, perhaps, in the future. TODO.
@ -111,31 +106,13 @@ func (k *EncryptedSSHKeyV1) Generate(force bool) error {
} }
k.Keys = append(k.Keys, pk) k.Keys = append(k.Keys, pk)
// We also need an encrypter/decrypter since this is an encrypted key. // We also need an encrypter/decrypter since this is an encrypted key.
// Upstream only currently supports bcrypt_pbkdf ("bcrypt"). if err := k.setCrypt(); err != nil {
// This should always eval to true, but is here for future planning in case other KDF are implemented. return err
switch k.KDFName {
case KdfBcrypt:
if k.Crypt.CryptKey, err = bcrypt_pbkdf.Key(k.Passphrase, k.KDFOpts.Salt, int(k.KDFOpts.Rounds), kdfKeyLen+len(k.KDFOpts.Salt)); err != nil {
return err
} else {
k.Crypt.PrivateKey = k.Crypt.CryptKey[0:kdfSplit]
k.Crypt.CryptSalt = k.Crypt.CryptKey[kdfSplit:]
}
default:
return errors.New("could not find KDF")
} }
switch k.CipherName { // And then we need to build the key buffer.
case CipherAes256Ctr: if err := k.buildKeybuf(); err != nil {
if k.Crypt.Cipher, err = aes.NewCipher(k.Crypt.PrivateKey); err != nil { return err
return err
} else {
k.Crypt.Stream = cipher.NewCTR(k.Crypt.Cipher, k.Crypt.CryptSalt)
// Can then be used as k.Crypt.Stream.XORKeyStream(dst []byte, src []byte)
}
default:
return errors.New("could not find Cipher")
} }
k.build()
return nil return nil
} }


@ -158,7 +135,6 @@ func (k *SSHKeyV1) Generate(force bool) error {
} }
if k.DefKeyType == KeyEd25519 { if k.DefKeyType == KeyEd25519 {
k.KeySize = keyEd25519 k.KeySize = keyEd25519
k.BlockSize = blockEd25519
} }
k.CipherName = CipherNull k.CipherName = CipherNull
k.KDFName = KdfNull k.KDFName = KdfNull
@ -184,34 +160,232 @@ func (k *SSHKeyV1) Generate(force bool) error {
return errors.New("unknown key type; could not generate private/public keypair") return errors.New("unknown key type; could not generate private/public keypair")
} }
k.Keys = append(k.Keys, pk) k.Keys = append(k.Keys, pk)
k.build() if err := k.buildKeybuf(); err != nil {
return err
}
return nil return nil
} }


func (k *SSHKeyV1) build() error { // buildKeybuf is where an EncryptedSSHKeyV1 key buffer is actually assembled.
// We actually assemble the key buffer here. Translation to bytes where needed, case switches (ED25519 vs. RSA), etc. // Entries are commented with their annotated reference.
k.Buffer.Truncate(0) // (see ref/(encrypted|plain)/(public|private).(rsa|ed25519) and ref/format.(ed25519|rsa) for details)
// First we need to do some prep for the common header. func (k *EncryptedSSHKeyV1) buildKeybuf() error {
kdfOptsBytes := []byte{} // TODO: error handling for each <buf>.Write()?
switch k.(type) { // Before anything, we want a clean buffer. Just in case.
case EncryptedSSHKeyV1: k.Buffer.Reset()
kdfOptsBytes = append(kdfOptsBytes, byte(len(k.KDFOpts.Salt))) // Add the common header.
if err := k.addHeader(); err != nil {
return err
} }
// For this, we can use a generic list and sequentially write. // Add the keypairs.
cipher := []byte(k.CipherName) // Since this is encrypted, the private key blobs are encrypted.
kdf := []byte(k.KDFName) // OpenSSH keys currently only support 1 keypair but support more *in theory*. This *seems* to be how they plan on doing it.
// But boy, is it a pain. So much wasted RAM and CPU cycles. They should use terminating byte sequences IMHO but whatever.
for _, i := range k.Keys { // 4.0.0 and 4.0.1
switch k.CipherName {
case CipherAes256Ctr:
i.BlockSize = k.Crypt.Cipher.BlockSize()
}
kbPtr, err := i.keyBlob(&k.Crypt, true)
if err != nil {
return err
}
k.Buffer.Write(*kbPtr)
}
return nil
}

// buildKeybuf is where an SSHKeyV1 key buffer is actually assembled.
// Entries are commented with their annotated reference.
// (see ref/(encrypted|plain)/(public|private).(rsa|ed25519) and ref/format.(ed25519|rsa) for details)
func (k *SSHKeyV1) buildKeybuf() error {
// TODO: error handling for each <buf>.Write()?
// Before anything, we want a clean buffer. Just in case.
k.Buffer.Reset()
// Add the common header.
if err := k.addHeader(); err != nil {
return err
}
// Add the keypairs.
// OpenSSH keys currently only support 1 keypair but support more *in theory*. This *seems* to be how they plan on doing it.
// But boy, is it a pain. So much wasted RAM and CPU cycles. They should use terminating byte sequences IMHO but whatever.
for _, i := range k.Keys { // 4.0.0 and 4.0.1
i.BlockSize = 8
kbPtr, err := i.keyBlob(nil, false)
if err != nil {
return err
}
k.Buffer.Write(*kbPtr)
}
return nil
}

func (k *SSHKeyV1) addHeader() error {
// TODO: error handling for each <buf>.Write()?
// First we need to do some prep for the plaintext header.
var kdfOptsBytes []byte
kdfOptsBytes = k.getKdfOptBytes() // 3.0.0
cipherBytes := []byte(k.CipherName) // 1.0
kdf := []byte(k.KDFName) // 2.0.0
// This is just cast to an array for visual readability.
commonHeader := [][]byte{ commonHeader := [][]byte{
[]byte(KeyV1Magic + "\x00"), []byte(KeyV1Magic + "\x00"), // 0
{byte(len(cipher))}, getBytelenByteArr(cipherBytes), // 1.0
cipher, cipherBytes, // 1.0.0
{byte(len(kdf))}, getBytelenByteArr(kdf), // 2.0
kdf, kdf, // 2.0.0
getBytelenByteArr(kdfOptsBytes), // 3.0
kdfOptsBytes, // 3.0.0
getByteInt(len(k.Keys)), // 4.0
} }
for _, v := range commonHeader { for _, v := range commonHeader {
if _, err := k.Buffer.Write(v); err != nil { if _, err := k.Buffer.Write(v); err != nil {
k.Buffer.Truncate(0)
return err return err
} }
} }

return nil
} }

func (k *EncryptedSSHKeyV1) getKdfOptBytes() []byte {
var kdfOptsBytes []byte // 3.0.0
// This is *probably* more efficient than using a buffer just for these bytes.
kdfOptsBytes = append(kdfOptsBytes, byte(len(k.KDFOpts.Salt))) // 3.0.0.0
kdfOptsBytes = append(kdfOptsBytes, k.KDFOpts.Salt...) // 3.0.0.0.0
kdfOptsBytes = append(kdfOptsBytes, byte(k.KDFOpts.Rounds)) // 3.0.0.1
return kdfOptsBytes
}

func (k *SSHKeyV1) getKdfOptBytes() []byte {
var kdfOptsBytes []byte // 3.0.0
// No-op; unencrypted keys' KDFOpts are encapsulated by a single null byte (which the caller implements).
return kdfOptsBytes
}

func (pk *SSHPrivKey) keyBlob(c *SSHCrypt, encrypt bool) (*[]byte, error) {
// TODO: error handling for each <buf>.Write()?
var keypairBytes bytes.Buffer // (4.0's children)
var pubkeyBytes bytes.Buffer // 4.0.0 children (4.0.0 itself is handled before writing to keypairBytes)
var privkeyBytes bytes.Buffer // 4.0.1 (and children)
pubkeyName := []byte(pk.PublicKey.KeyType) // (4.0.0.0.0, cast to var because I'm lazy)
pubkeyBytes.Write(getBytelenByteArr(pubkeyName)) // 4.0.0.0
pubkeyBytes.Write(pubkeyName) // 4.0.0.0.0
// TODO: Optimize?
/*
THE PUBLIC KEY
This is unencrypted, even if it's an encrypted key.
*/
switch pk.PublicKey.KeyType {
case KeyEd25519:
pubkeyBytes.Write(getBytelenByteArr(pk.PublicKey.Key.([]byte))) // 4.0.0.1
pubkeyBytes.Write(pk.PublicKey.Key.([]byte)) // 4.0.0.1.0
case KeyRsa:
// How messy.
var en bytes.Buffer // 4.0.0.1 and 4.0.0.2
// TODO: does e need getByteInt()?
e := pk.PublicKey.Key.E.Bytes() // 4.0.0.1.0
// TODO: does n need nullbyte prefix?
n := pk.PublicKey.Key.N.Bytes() // 4.0.0.2.0
en.Write(getBytelenByteArr(e)) // 4.0.0.1
en.Write(e) // 4.0.0.1.0
en.Write(getBytelenByteArr(n)) // 4.0.0.2
en.Write(n) // 4.0.0.2.0
pubkeyBytes.Write(getBytelenByteArr(en.Bytes())) // 4.0.0
if _, err := en.WriteTo(&pubkeyBytes); err != nil { // (4.0.0 children)
return nil, err
}
}
/*
THE PRIVATE KEY
This is encrypted if it's an encrypted key, otherwise it's just plain readable bytes.
*/
// First we need two checksums.
for i := 1; i <= 2; i++ {
privkeyBytes.Write(pk.Checksum) // 4.0.1.0 and 4.0.1.1
}
// And then add the public keys. Yes, the public keys are included in the private keys.
privkeyBytes.Write(getBytelenByteArr(pubkeyName)) // 4.0.1.2.0
privkeyBytes.Write(pubkeyName) // 4.0.1.2.0.0
switch pk.PublicKey.KeyType {
case KeyEd25519:
// This is easy.
privkeyBytes.Write(pubkeyBytes.Bytes()) // 4.0.1.2.1
if _, err := pubkeyBytes.WriteTo(&privkeyBytes); err != nil { // 4.0.1.2.1.0
return nil, err
}
case KeyRsa:
// This is not. We more or less have to do the same thing as the public key, BUT with e and n flipped. Gorram it.
var ne bytes.Buffer // (4.0.1.2 children)
// TODO: does n need nullbyte prefix?
n := pk.PublicKey.Key.N.Bytes() // 4.0.1.2.1.0
// TODO: does e need getByteInt()?
e := pk.PublicKey.Key.E.Bytes() // 4.0.1.2.2.0
ne.Write(getBytelenByteArr(n)) // 4.0.1.2.1
ne.Write(n) // 4.0.1.2.1.0
ne.Write(getBytelenByteArr(e)) // 4.0.1.2.2
ne.Write(e) // 4.0.1.2.2.0
if _, err := ne.WriteTo(&privkeyBytes); err != nil { // (4.0.1.2 children)
return nil, err
}
}
// And then we add the *actual* private keys.
switch pk.PublicKey.KeyType {
case KeyEd25519:
privkeyBytes.Write(getBytelenByteArr(pk.KeyAlt)) // 4.0.1.3
privkeyBytes.Write(pk.KeyAlt) // 4.0.1.3.0
case KeyRsa:
var dcpq bytes.Buffer // 4.0.1.3 to 4.0.1.6
d := pk.Key.D.Bytes() // 4.0.1.3.0
crt := pk.Key.Precomputed.Qinv.Bytes() // 4.0.1.4.0
// TODO: does p need nullbyte prefix?
p := pk.Key.Primes[0].Bytes() // 4.0.1.5.0
// TODO: does q need nullbyte prefix?
q := pk.Key.Primes[1].Bytes() // 4.0.1.6.0
dcpq.Write(getBytelenByteArr(d)) // 4.0.1.3
dcpq.Write(d) // 4.0.1.3.0
dcpq.Write(getBytelenByteArr(crt)) // 4.0.1.4
dcpq.Write(crt) // 4.0.1.4.0
dcpq.Write(getBytelenByteArr(p)) // 4.0.1.5
dcpq.Write(p) // 4.0.1.5.0
dcpq.Write(getBytelenByteArr(q)) // 4.0.1.6
dcpq.Write(q) // 4.0.1.6.0
if _, err := dcpq.WriteTo(&privkeyBytes); err != nil { // 4.0.1.3 to 4.0.1.6
return nil, err
}
}
// Add the comment.
privkeyBytes.Write(getBytelenByteArr([]byte(pk.Comment))) // 4.0.1.4 (ED25519), 4.0.1.7 (RSA)
privkeyBytes.Write([]byte(pk.Comment)) // 4.0.1.4.0 (ED25519), 4.0.1.7.0 (RSA)
// Add padding
pad := 0
n := 0
for len(privkeyBytes.Bytes()) % pk.BlockSize != 0 { // 4.0.1.5 (ED25519), 4.0.1.8 (RSA)
n++
pad = n & pk.BlockSize
privkeyBytes.Write(getSingleByteInt(pad))
}
// Check if the private key should be encrypted or not.
if encrypt {
// We encrypt here to a "new" buffer.
// We actually just clear the buffer and then write the new encrypted data to it, and then clear the intermediate byte slice.
if c == nil || c.Stream == nil {
return nil, errors.New("if encrypting, you must specify a populated SSHCrypt in c")
}
var encBytes []byte
c.Stream.XORKeyStream(encBytes, privkeyBytes.Bytes())
privkeyBytes.Reset()
privkeyBytes.Write(encBytes)
encBytes = []byte{}
}
// Get the respective lengths and add child buffers to buffer.
keypairBytes.Write(getByteInt(len(pubkeyBytes.Bytes()))) // 4.0.0
if _, err := pubkeyBytes.WriteTo(&keypairBytes); err != nil { // (4.0.0 children)
return nil, err
}
keypairBytes.Write(getByteInt(len(privkeyBytes.Bytes()))) // 4.0.1
if _, err := privkeyBytes.WriteTo(&keypairBytes); err != nil { // (4.0.1 children)
return nil, err
}
// Done!
kpSlice := keypairBytes.Bytes()
return &kpSlice, nil
}

View File

@ -19,90 +19,18 @@
package main package main


import ( import (
"crypto" `crypto`
"crypto/aes" `crypto/aes`
"crypto/cipher" `crypto/cipher`
"crypto/ed25519" `crypto/ed25519`
"encoding/hex" `encoding/hex`
"fmt" `fmt`


"github.com/dchest/bcrypt_pbkdf" `github.com/dchest/bcrypt_pbkdf`
) )


// ssh-keygen -f /tmp/tmp2xzvpjhn -q -o -t ed25519 -N test -a 100 /*
// private Same key as private.ed25519 example.
/* on-disk format
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAZQzNZ6B
eWtpsLgQvGbcuMAAAAZAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFjgZ791hHftK4GY
uhnIN/1JdZqA17hIlNdKr+ljJ9bfAAAAoN0XZgxeA2SLXGZXqZi9TqeQHU7PERiJA9F0+p
2NtNP4Y1Rey8C1EnF5mhzy8AZs6YJsE+xnQUSI/+Kbmi6MACQALaPO7CgtKwnfbFHuxzrD
1EG83K08w2NE2txlQPqflQcFoVBIzcXNVFv+3A5DM7BBz0jLFi5CCwl2PEhMhcpElvV+LW
PGXBV9IVdOeHm/hesRfuWTHcUalrqar1CmLWo=
-----END OPENSSH PRIVATE KEY-----
*/
/* actual bytes (hex repr)
00000000: 6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00 00 openssh-key-v1..
00000010: 00 00 0a 61 65 73 32 35 36 2d 63 74 72 00 00 00 ...aes256-ctr...
00000020: 06 62 63 72 79 70 74 00 00 00 18 00 00 00 10 19 .bcrypt.........
00000030: 43 33 59 e8 17 96 b6 9b 0b 81 0b c6 6d cb 8c 00 C3Y.........m...
00000040: 00 00 64 00 00 00 01 00 00 00 33 00 00 00 0b 73 ..d.......3....s
00000050: 73 68 2d 65 64 32 35 35 31 39 00 00 00 20 58 e0 sh-ed25519... X.
00000060: 67 bf 75 84 77 ed 2b 81 98 ba 19 c8 37 fd 49 75 g.u.w.+.....7.Iu
00000070: 9a 80 d7 b8 48 94 d7 4a af e9 63 27 d6 df 00 00 ....H..J..c'....
00000080: 00 a0 dd 17 66 0c 5e 03 64 8b 5c 66 57 a9 98 bd ....f.^.d.\fW...
00000090: 4e a7 90 1d 4e cf 11 18 89 03 d1 74 fa 9d 8d b4 N...N......t....
000000a0: d3 f8 63 54 5e cb c0 b5 12 71 79 9a 1c f2 f0 06 ..cT^....qy.....
000000b0: 6c e9 82 6c 13 ec 67 41 44 88 ff e2 9b 9a 2e 8c l..l..gAD.......
000000c0: 00 24 00 2d a3 ce ec 28 2d 2b 09 df 6c 51 ee c7 .$.-...(-+..lQ..
000000d0: 3a c3 d4 41 bc dc ad 3c c3 63 44 da dc 65 40 fa :..A...<.cD..e@.
000000e0: 9f 95 07 05 a1 50 48 cd c5 cd 54 5b fe dc 0e 43 .....PH...T[...C
000000f0: 33 b0 41 cf 48 cb 16 2e 42 0b 09 76 3c 48 4c 85 3.A.H...B..v<HL.
00000100: ca 44 96 f5 7e 2d 63 c6 5c 15 7d 21 57 4e 78 79 .D..~-c.\.}!WNxy
00000110: bf 85 eb 11 7e e5 93 1d c5 1a 96 ba 9a af 50 a6 ....~.........P.
00000120: 2d 6a -j
//
6f70656e7373682d6b65792d763100 authmagic
0000000a 10
6165733235362d637472 "aes256-ctr"
00000006 6
626372797074 "bcrypt"
00000018 24
00000010 16
19433359e81796b69b0b810bc66dcb8c salt
00000064 100
00000001 1
00000033 51
0000000b 11
7373682d65643235353139 "ssh-ed25519"
00000020 32
58e067bf758477ed2b8198ba19c837fd49759a80d7b84894d74aafe96327d6df pubkey
000000a0 160 length of encrypted private info
dd17660c5e03648b5c6657a998bd4ea7 16*10 bytes (160 bytes)
901d4ecf11188903d174fa9d8db4d3f8
63545ecbc0b51271799a1cf2f0066ce9
826c13ec67414488ffe29b9a2e8c0024
002da3ceec282d2b09df6c51eec73ac3
d441bcdcad3cc36344dadc6540fa9f95
0705a15048cdc5cd545bfedc0e4333b0
41cf48cb162e420b09763c484c85ca44
96f57e2d63c65c157d21574e7879bf85
eb117ee5931dc51a96ba9aaf50a62d6a
*/
// public
/* on-disk format
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjgZ791hHftK4GYuhnIN/1JdZqA17hIlNdKr+ljJ9bf bts@dawid.r00t.space
*/
/* actual bytes (hex repr)
00000000: 00 00 00 0b 73 73 68 2d 65 64 32 35 35 31 39 00 ....ssh-ed25519.
00000010: 00 00 20 58 e0 67 bf 75 84 77 ed 2b 81 98 ba 19 .. X.g.u.w.+....
00000020: c8 37 fd 49 75 9a 80 d7 b8 48 94 d7 4a af e9 63 .7.Iu....H..J..c
00000030: 27 d6 df '..
//
0000000b 11
7373682d65643235353139 "ssh-ed25519"
00000020 32
58e067bf758477ed2b8198ba19c837fd49759a80d7b84894d74aafe96327d6df
*/ */


func main() { func main() {
@ -126,7 +54,7 @@ func main() {
encData = make([]byte, lenPlain) encData = make([]byte, lenPlain)


// Import salt // Import salt
if s, err := hex.DecodeString("19433359e81796b69b0b810bc66dcb8c"); err != nil { if s, err := hex.DecodeString("50132f72900d68e0a31f9d75b6f0a5bc"); err != nil {
fmt.Println(err) fmt.Println(err)
return return
} else { } else {
@ -134,7 +62,13 @@ func main() {
} }


// Import encrypted data // Import encrypted data
if b, err := hex.DecodeString("dd17660c5e03648b5c6657a998bd4ea7901d4ecf11188903d174fa9d8db4d3f863545ecbc0b51271799a1cf2f0066ce9826c13ec67414488ffe29b9a2e8c0024002da3ceec282d2b09df6c51eec73ac3d441bcdcad3cc36344dadc6540fa9f950705a15048cdc5cd545bfedc0e4333b041cf48cb162e420b09763c484c85ca4496f57e2d63c65c157d21574e7879bf85eb117ee5931dc51a96ba9aaf50a62d6a"); err != nil { if b, err := hex.DecodeString(
"c49777cd0d1a7d37db77a1814991278f8ce99d572e2c666b93b99867425c60da" +
"4652fddb8555098532b51beeee2959f9db5cf5a0905052720c5de25f2c4dd87e" +
"bcc7bb5ea3d7bcbeacc6b732e4c39295d9991a97ef3f0838f8a9bfd43edb3403" +
"189649088f6cfb78946fb914e358ac6abc64691072f5f2788534d9d42d7f406b" +
"c5090b30df23cb7dd8c5cb938e41facd6e38e8845b8160bff840598118d447c2",
); err != nil {
fmt.Println(err) fmt.Println(err)
return return
} else { } else {
@ -143,7 +77,10 @@ func main() {


// ED25519 keys // ED25519 keys
// This is used to validate decrypted keys. // This is used to validate decrypted keys.
if edk, err := hex.DecodeString("cceabbe370f139c3d3915018d8511e0663b62840d6b328426ac3df4e75ce6adf58e067bf758477ed2b8198ba19c837fd49759a80d7b84894d74aafe96327d6df"); err != nil { if edk, err := hex.DecodeString(
"ce6e2b8d638c9d5219dff455af1a90d0a5b72694cfcedfb93bc1e1b1816dee98" +
"bfa2031aa5463113e40e16896af503c5299ead76b09cb63846f41cc4de1740f6",
); err != nil {
fmt.Println(err) fmt.Println(err)
return return
} else { } else {
@ -205,17 +142,4 @@ func main() {
// fmt.Printf("Encrypted data: %v\n", hex.EncodeToString(encData)) // fmt.Printf("Encrypted data: %v\n", hex.EncodeToString(encData))
fmt.Printf("Decrypted data?: %v\n", hex.EncodeToString(decrypted)) fmt.Printf("Decrypted data?: %v\n", hex.EncodeToString(decrypted))


/* decrypted now correctly returns:
54efc132 checksum
54efc132 checksum matches!
0000000b 11
7373682d65643235353139 "ssh-ed25519"
00000020 32
58e067bf758477ed2b8198ba19c837fd49759a80d7b84894d74aafe96327d6df pubkey
00000040 64
cceabbe370f139c3d3915018d8511e0663b62840d6b328426ac3df4e75ce6adf58e067bf758477ed2b8198ba19c837fd49759a80d7b84894d74aafe96327d6df private key
00000014 20
6274734064617769642e723030742e7370616365 "bts@dawid.r00t.space"
010203040506070809 (padding)
*/
} }

View File

@ -28,374 +28,8 @@ import (
"github.com/dchest/bcrypt_pbkdf" "github.com/dchest/bcrypt_pbkdf"
) )


// ssh-keygen -f /tmp/tmp2xzvpjhn -q -o -t rsa -b 4096 -C "This is a comment string" -N test -a 100 /*
// private Same key as private.rsa example.
/* on-disk format
-----BEGIN OPENSSH PRIVATE KEY-----
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
ZnrXZl+8QIW1MSvaaQFmJFqTs=
-----END OPENSSH PRIVATE KEY-----
*/
/* actual bytes (hex repr)
00000000: 6f 70 65 6e 73 73 68 2d 6b 65 79 2d 76 31 00 00 openssh-key-v1..
00000010: 00 00 0a 61 65 73 32 35 36 2d 63 74 72 00 00 00 ...aes256-ctr...
00000020: 06 62 63 72 79 70 74 00 00 00 18 00 00 00 10 07 .bcrypt.........
00000030: d4 b0 7c 0b 12 83 48 91 64 88 00 8d 6e 13 0b 00 ..|...H.d...n...
00000040: 00 00 64 00 00 00 01 00 00 02 17 00 00 00 07 73 ..d............s
00000050: 73 68 2d 72 73 61 00 00 00 03 01 00 01 00 00 02 sh-rsa..........
00000060: 01 00 b7 ce c0 46 01 ce 2a 12 f0 c9 24 cb 9a 30 .....F..*...$..0
00000070: eb 99 00 66 81 2c b1 43 69 19 3f 30 b2 b9 fd d4 ...f.,.Ci.?0....
00000080: af cb 30 0c 91 8f 2a 77 d6 44 10 f3 61 7a e7 c8 ..0...*w.D..az..
00000090: ca 31 8c 25 7d 3c 4d f4 e2 c4 10 8b bb e9 3a 86 .1.%}<M.......:.
000000a0: 89 4b a1 4b 35 75 f2 f7 21 50 bc 38 1d cb fb 74 .K.K5u..!P.8...t
000000b0: 2c 7a 19 68 66 fd 31 84 ac e9 67 61 ad da 0f c2 ,z.hf.1...ga....
000000c0: 99 2f 6c 86 6d 75 69 91 9f c2 2d 9c 4b f0 de 40 ./l.mui...-.K..@
000000d0: 5a 8c 76 d5 19 aa 2a 53 29 dc 68 25 77 72 29 a5 Z.v...*S).h%wr).
000000e0: d0 b7 53 a7 82 5a 89 b9 52 75 f9 c0 25 e2 15 34 ..S..Z..Ru..%..4
000000f0: 3c 6c 88 cd 66 90 a2 21 f8 ae 9e f6 75 ee 46 4d <l..f..!....u.FM
00000100: c7 d1 18 da 41 05 07 ea 5d 6b 64 89 dd 60 af d8 ....A...]kd..`..
00000110: a6 64 64 92 db 3e 27 9f 1a 78 24 0d b8 ab bd a6 .dd..>'..x$.....
00000120: c5 07 14 c9 63 66 50 a7 20 81 e7 fa 5d 47 2c 14 ....cfP. ...]G,.
00000130: 28 b0 7e ae 5d 15 b6 4e a1 e2 a7 50 85 12 fe 9a (.~.]..N...P....
00000140: b6 55 f8 6a 31 34 86 d3 cc a1 dd 8e 90 ac c5 c9 .U.j14..........
00000150: fb a4 d6 e7 67 50 7f ba b9 f3 a7 f6 8c 74 81 42 ....gP.......t.B
00000160: af 2a 37 01 d3 1a 8a 9b 75 11 95 8a a7 71 87 ba .*7.....u....q..
00000170: 70 2e d9 34 d3 85 af ce e4 23 80 e9 5e 0e 7e 9b p..4.....#..^.~.
00000180: c0 f4 d2 33 67 fc 77 03 74 16 7b 7f 09 26 fb 6f ...3g.w.t.{..&.o
00000190: db 6d 05 aa d1 cf d1 91 82 48 45 b0 14 e1 81 53 .m.......HE....S
000001a0: bf 0d 1d 3c 3b 1f ad bb 25 a3 f1 d1 51 f9 b6 84 ...<;...%...Q...
000001b0: 63 3d 8c 16 90 fc d8 ca d0 5a ac 2a eb 23 db f1 c=.......Z.*.#..
000001c0: 9a 37 e4 80 a0 08 91 03 19 c1 16 d4 7b d9 24 b3 .7..........{.$.
000001d0: 99 42 54 3b 88 a0 f6 12 79 52 b2 d8 e1 29 0f 30 .BT;....yR...).0
000001e0: 29 f5 42 ae be 9c 0c 8e 36 cf 32 96 86 5c d6 64 ).B.....6.2..\.d
000001f0: 3c 89 24 d5 66 eb f4 97 18 09 39 9a 1a c0 96 fe <.$.f.....9.....
00000200: 1e dc 3b 5f 87 1b f5 ef 0b 4d 44 e0 ea 27 62 0d ..;_.....MD..'b.
00000210: 20 51 42 e0 bf cf 67 7b 4d b0 25 53 21 21 a3 f0 QB...g{M.%S!!..
00000220: 74 5a a4 d0 58 63 31 73 32 57 85 5a 5c ec be 3a tZ..Xc1s2W.Z\..:
00000230: c4 40 3d 04 ff 0c c0 c5 8b 7c 04 90 4b 40 21 25 .@=......|..K@!%
00000240: c2 bc 2a 63 a2 0e bb 30 9c c6 f3 e6 5d b3 01 a0 ..*c...0....]...
00000250: 58 b8 da ce 07 e7 1b 38 f3 f3 59 54 33 f6 9b 19 X......8..YT3...
00000260: 8f 07 00 00 07 50 96 6e 2c e4 35 24 2f ef 09 78 .....P.n,.5$/..x
00000270: 7f 6e 8d 93 a5 63 09 2e 3f 3b c9 86 b4 41 98 c8 .n...c..?;...A..
00000280: 1e 80 49 c5 c9 44 41 9e ff c0 52 14 01 dc 1e f5 ..I..DA...R.....
00000290: bc 0e 4d 6a ed eb 7d 05 88 0b c3 f7 31 69 8b 9b ..Mj..}.....1i..
000002a0: ce ec ea e0 8e 5e 05 f7 9f 4d 22 de 95 3c 89 9c .....^...M"..<..
000002b0: 32 71 85 0e 80 e8 04 f9 b1 a7 9b ce c3 1b ba 11 2q..............
000002c0: c0 8d b6 0f 9b d2 20 6b c3 d7 bf ef 74 89 5e 4f ...... k....t.^O
000002d0: 4e 37 20 64 9f 92 45 44 f4 a2 ce a5 b9 df b9 cc N7 d..ED........
000002e0: 0a 2b d8 f3 ba 70 f4 ba 2e 7f 42 96 04 65 c9 ea .+...p....B..e..
000002f0: de 11 86 30 f9 c8 32 fe 84 ef 54 85 29 97 9d 0d ...0..2...T.)...
00000300: 6e a0 79 f9 d5 c4 0e 39 6b 09 8f c5 09 44 8d 26 n.y....9k....D.&
00000310: de 3c b4 84 b0 33 4a fa ca ba 37 1b 52 c3 7c 12 .<...3J...7.R.|.
00000320: 0a 56 23 17 0c 1d 0a 39 34 8a 15 1c 9f b8 aa b1 .V#....94.......
00000330: 04 9f 52 cf 0c 08 c7 71 44 af 31 42 59 a9 08 48 ..R....qD.1BY..H
00000340: f3 dc 62 e5 83 1f ac 08 72 0b 1c 81 35 06 f1 db ..b.....r...5...
00000350: 1e 79 40 de f5 2d c4 6c 97 d6 36 3c da 0f f7 e2 .y@..-.l..6<....
00000360: 25 8e 26 37 d2 e0 9f 26 09 9b bf ea c7 88 19 19 %.&7...&........
00000370: 8b 78 37 4d 24 24 53 7f e5 49 a2 ab 3d dd af 5f .x7M$$S..I..=.._
00000380: 7f db 73 9c 39 21 06 4b 04 f6 ff cf eb 55 44 db ..s.9!.K.....UD.
00000390: 53 31 79 03 8e 11 d0 cc 62 29 92 bc 6d 06 00 58 S1y.....b)..m..X
000003a0: 4d 40 68 a2 89 1d c7 48 c9 c1 6b e3 2c 2a 08 e9 M@h....H..k.,*..
000003b0: 6c aa 2d de c4 dd d1 a2 ab 3b 01 8a 0b 0f 16 6a l.-......;.....j
000003c0: 15 ac 87 0a 30 c8 0c c8 97 db f1 5a f7 e8 c2 91 ....0......Z....
000003d0: 5b 36 16 f2 37 a6 64 6e 43 c6 65 f7 56 9a 5e d1 [6..7.dnC.e.V.^.
000003e0: 85 0a d8 cd 05 40 06 d3 89 56 8d b5 53 93 e7 80 .....@...V..S...
000003f0: e7 52 ac e8 f0 6b 70 f1 e9 9d 86 b9 44 5d 9c 1a .R...kp.....D]..
00000400: 7a 64 76 bc bf 48 44 00 a5 8e 5a 5a 73 d2 c2 0d zdv..HD...ZZs...
00000410: 63 0a 99 85 bb f4 c6 91 ab b6 1e e4 51 5a a6 4a c...........QZ.J
00000420: 72 7e 7b ac 4a 5e d7 bb 5f 76 7c 7d cf 00 35 90 r~{.J^.._v|}..5.
00000430: 42 31 28 3d 92 44 58 63 70 2a 99 5e 79 2b de 1d B1(=.DXcp*.^y+..
00000440: 5a c7 dd 62 48 98 7b 9f e4 b0 a6 f1 83 7c e4 fb Z..bH.{......|..
00000450: aa 03 2f f4 67 1a 86 be 8c 7e 4f 9b e3 71 82 12 ../.g....~O..q..
00000460: ea d0 a6 f1 b4 29 88 86 3b f8 0a f1 7a 98 14 f1 .....)..;...z...
00000470: ff be d6 c8 1e 7f 59 de 5b 8c 71 b9 f5 71 fc 55 ......Y.[.q..q.U
00000480: 6c c5 6a ee 22 be 1b 57 d4 8f 8c a7 6a 37 98 47 l.j."..W....j7.G
00000490: c6 7d 0c eb 43 ea d1 01 35 5e 54 1a 57 c2 54 ae .}..C...5^T.W.T.
000004a0: 81 4f 05 8a 03 61 92 f4 9d 96 23 6c 88 42 8e 5f .O...a....#l.B._
000004b0: 54 da fe fd 1a 5b 8c a1 2d 85 cf 38 33 d3 8d 81 T....[..-..83...
000004c0: 6c 6e 0e 20 51 43 f3 3e 35 3c 47 1a bc 97 8d 28 ln. QC.>5<G....(
000004d0: d1 ac 89 a7 24 d5 aa b3 e7 c4 80 15 c5 cd 3a 6f ....$.........:o
000004e0: 31 c2 58 ce f1 31 25 74 e6 92 c6 e4 95 a2 a8 ef 1.X..1%t........
000004f0: be e7 85 a9 fe 1c 72 73 79 ea 1f dc 5b 49 2a 83 ......rsy...[I*.
00000500: a4 af f7 b3 94 5a ef 50 3a 95 dc 52 b2 14 74 17 .....Z.P:..R..t.
00000510: 2b b5 40 54 b1 06 34 2f 2b de 6b c3 8a d1 66 c1 +.@T..4/+.k...f.
00000520: a5 c6 d8 86 85 b8 06 7f 52 97 41 b3 69 91 35 2d ........R.A.i.5-
00000530: 5d f1 29 1b 9e 3c 74 6a 71 e2 bd a7 96 fd dd ac ].)..<tjq.......
00000540: 29 d0 e2 f3 fa df d1 f0 fd 33 da 75 bc 61 51 d3 )........3.u.aQ.
00000550: ee 27 f6 19 9e 76 c3 b9 e8 72 fb 63 b5 4a d7 8b .'...v...r.c.J..
00000560: 0f be 2b e8 4f 10 d7 e4 83 39 c6 e6 33 64 50 70 ..+.O....9..3dPp
00000570: 74 ad dc 5a 2b d8 c4 be 58 48 c2 91 bd b2 74 0d t..Z+...XH....t.
00000580: 3a a3 25 c3 50 39 6c e2 8e 08 6e ec dd 62 56 f4 :.%.P9l...n..bV.
00000590: 8f b7 94 7b 84 e8 57 59 b1 c7 e6 dd 91 22 3e 3f ...{..WY.....">?
000005a0: 82 8e 42 53 a7 ec 6d 98 7a d6 1b d2 17 9c 22 9a ..BS..m.z.....".
000005b0: 20 e8 d9 7e 61 58 cb 0b e7 34 22 76 98 b4 69 5c ..~aX...4"v..i\
000005c0: 78 4c 46 3c ac 3e a7 d5 38 05 6d 50 62 a8 95 f8 xLF<.>..8.mPb...
000005d0: ae 64 54 9b d5 84 84 a6 03 63 ab 81 bc 43 e6 fd .dT......c...C..
000005e0: e0 ee 12 47 70 51 b5 3c 97 0f 06 3d f2 f0 ff 2f ...GpQ.<...=.../
000005f0: d6 55 b7 f8 10 29 be 54 5c c8 41 f7 32 1d 31 30 .U...).T\.A.2.10
00000600: 4e eb a2 10 fd f8 fd ad 7e 1b c8 ac cd 4d 99 0c N.......~....M..
00000610: 05 8b 30 81 7e 85 e2 c5 69 5a b9 2c 1e 12 9a c7 ..0.~...iZ.,....
00000620: 47 1f 33 8f dd 39 4e de 16 07 14 50 c1 90 61 e0 G.3..9N....P..a.
00000630: 7c 13 5c be 87 f0 12 60 b3 62 06 cb c1 69 c8 5b |.\....`.b...i.[
00000640: 9d da 26 fb 3d ff 5e 7d 68 fd 51 a5 73 40 2d bc ..&.=.^}h.Q.s@-.
00000650: c1 dc 7f 49 a1 cb 9c 34 10 0b 9b 3d 0b b8 b8 63 ...I...4...=...c
00000660: 9c 69 c7 d4 74 90 ab 83 c8 91 8a d0 3a e6 2e ee .i..t.......:...
00000670: 43 16 5e 45 2f 85 4d 8d 41 32 18 6c 21 f7 42 ee C.^E/.M.A2.l!.B.
00000680: 4a 3c c6 14 51 5a dc 7c 08 94 08 38 53 85 03 f5 J<..QZ.|...8S...
00000690: c4 d5 78 1e 98 4c ad 93 cf 7a 8d 17 a6 8d 67 8b ..x..L...z....g.
000006a0: 34 66 af ba e3 62 05 5d 5b 6e db 00 07 b5 92 31 4f...b.][n.....1
000006b0: d3 04 0d bf ec 8b 97 82 b3 9c 39 11 16 f2 03 7e ..........9....~
000006c0: 21 8b fa ba 46 c5 2c 56 18 0a ee f2 41 d9 18 f2 !...F.,V....A...
000006d0: 14 b0 b6 48 0b 73 82 87 5a d9 da ce 44 96 c3 68 ...H.s..Z...D..h
000006e0: 2e a2 a6 97 b5 fe 43 b1 07 d9 3e 19 76 b2 54 0d ......C...>.v.T.
000006f0: bf da 2a e2 23 bc 1a 84 d6 5e 0d 67 02 51 3b 8c ..*.#....^.g.Q;.
00000700: c4 42 a2 5f b9 83 aa df a4 92 d0 9e 3d fd 99 1f .B._........=...
00000710: 9f 47 47 0b b7 33 69 f6 34 dd 50 da b2 6d 12 9c .GG..3i.4.P..m..
00000720: 3b a0 96 ad 79 71 1f 0e e4 41 9c 12 26 eb 8d a4 ;...yq...A..&...
00000730: 26 74 b2 cf 77 e8 f4 a3 f7 6c e9 e9 e2 49 b4 d1 &t..w....l...I..
00000740: fc c7 78 ef 31 8d bd 67 78 55 6c 0f 98 78 eb e6 ..x.1..gxUl..x..
00000750: e8 32 49 16 d7 82 80 f2 3f 7e 39 21 b2 9b 42 bb .2I.....?~9!..B.
00000760: a6 ca 2d 78 03 99 ca 4e d3 cb 2d 03 6c 9b ed 80 ..-x...N..-.l...
00000770: b2 35 80 91 98 42 21 35 e2 d8 42 c8 f5 3a 4d d5 .5...B!5..B..:M.
00000780: 9f e0 be d8 89 d4 78 40 16 40 24 b1 f6 68 cc 56 ......x@.@$..h.V
00000790: 69 78 d4 31 eb 2a 07 a2 0e d0 6e 57 55 51 e1 b0 ix.1.*....nWUQ..
000007a0: 30 db 13 50 e9 4c 92 9a 02 8a 5d c2 53 40 e3 43 0..P.L....].S@.C
000007b0: 4f 22 50 e3 f4 9d e1 71 bb 85 08 75 d2 80 05 0e O"P....q...u....
000007c0: 49 55 44 ba 71 b7 1e a3 6c 29 37 ad 65 93 e2 b5 IUD.q...l)7.e...
000007d0: bc a2 8b c3 8e 59 ce a9 1f 26 cd 1c a8 aa 4b d9 .....Y...&....K.
000007e0: fb c1 c6 05 ae 46 ae 3f 55 9b 3a 6e bf 89 ff 56 .....F.?U.:n...V
000007f0: 9f f3 65 c3 cb a4 b4 b9 1f 66 5f fd a3 97 18 8f ..e......f_.....
00000800: e2 3e a4 56 c8 02 c4 7a 80 62 84 4d 40 4f ab 41 .>.V...z.b.M@O.A
00000810: a0 fa 83 fd 0d d6 6e 4d b5 11 15 f0 26 19 7f 4c ......nM....&..L
00000820: 89 a1 bf 28 24 6b a9 96 6c a2 97 3b 0f 3a fa 43 ...($k..l..;.:.C
00000830: 15 48 96 a5 6b fe 21 53 df aa a3 cc d2 ab 01 1b .H..k.!S........
00000840: 7f 91 47 0c bd c0 4a f7 cf e1 70 3d e7 04 0f 4d ..G...J...p=...M
00000850: 77 77 b0 68 76 9d 40 35 37 7c c7 66 4f 40 6b 5d ww.hv.@57|.fO@k]
00000860: 69 35 6a a3 30 45 c4 33 4a 1e 2c e6 02 ea 2b 1e i5j.0E.3J.,...+.
00000870: c6 66 35 2d 14 b5 99 6d ad 45 1a 4c b8 86 c6 61 .f5-...m.E.L...a
00000880: 43 dc 25 f8 f1 bc f0 ed 25 3f eb c9 73 34 32 ea C.%.....%?..s42.
00000890: da 35 a6 af c9 82 74 9f a0 ec 68 0a 88 1d b0 61 .5....t...h....a
000008a0: 71 ea 37 fa 83 38 1e c9 0a 6a fa 2f 26 9d 9d a0 q.7..8...j./&...
000008b0: 7c 8f 30 21 61 e2 6c 9a 4c 21 c2 56 0c ed 81 1b |.0!a.l.L!.V....
000008c0: df 6b e4 02 d3 6a e2 f1 1f 88 43 51 24 1e 77 9a .k...j....CQ$.w.
000008d0: 22 f8 b6 9a 8e 3e ea a6 76 e7 15 01 43 a6 6b 3a "....>..v...C.k:
000008e0: 92 d4 da ce 9f 4f 9b 61 e3 f7 e0 aa 76 56 c8 18 .....O.a....vV..
000008f0: ec fb 53 30 34 57 d5 1e 74 e7 ec 89 cf 03 8c 9a ..S04W..t.......
00000900: 73 f3 83 43 83 e8 22 d2 f5 0c 3a 77 75 aa 0e 63 s..C.."...:wu..c
00000910: b1 27 a2 14 db 74 90 e4 88 f7 ee 91 78 2a 90 de .'...t......x*..
00000920: 32 f4 ab 22 60 1a f7 b1 90 fc c6 a2 92 e4 2e 2f 2.."`........../
00000930: 8b 69 ca ac e9 94 b1 27 e9 f9 15 32 b6 d8 c3 b7 .i.....'...2....
00000940: ce 08 f9 91 d2 69 22 0b ce ee d7 d4 e6 15 15 23 .....i"........#
00000950: e6 3e 41 bc d2 71 54 fd 3a 7f 73 70 c0 4b 12 58 .>A..qT.:.sp.K.X
00000960: 71 54 13 ec 5f 17 f5 1b aa 99 e8 e5 cd 59 ac 7a qT.._........Y.z
00000970: f1 7d ae cd 0e 89 26 00 24 03 ab 87 a4 22 e4 22 .}....&.$...."."
00000980: a6 fb 11 86 b5 bb 7d b2 5f af fe da d2 47 fd 74 ......}._....G.t
00000990: 1b 24 61 aa 3b 96 12 34 21 42 af 10 de ce fe 00 .$a.;..4!B......
000009a0: c0 0b 37 a6 67 ad 76 65 fb c4 08 5b 53 12 bd a6 ..7.g.ve...[S...
000009b0: 90 16 62 45 a9 3b ..bE.;
//
6f70656e7373682d6b65792d763100 authmagic
0000000a 10
6165733235362d637472 "aes256-ctr"
00000006 6
626372797074 "bcrypt"
00000018 24
00000010 16
07d4b07c0b128348916488008d6e130b salt
00000064 100
00000001 1
00000217 535
00000007 7
7373682d727361 "ssh-rsa"
00000003 3
010001 65537 public exponent
00000201 513
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4af ((32*16) + 1) bytes (513 bytes) modulus (ASN.1 format)
cb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc299
2f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7
d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab6
55f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0
f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a
37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1e
dc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2
bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07
00000750 1872
966e2ce435242fef09787f6e8d93a563092e3f3bc986b44198c81e8049c5c944 ((32*58) + 16) bytes (1872 bytes) private key
419effc0521401dc1ef5bc0e4d6aedeb7d05880bc3f731698b9bceeceae08e5e
05f79f4d22de953c899c3271850e80e804f9b1a79bcec31bba11c08db60f9bd2
206bc3d7bfef74895e4f4e3720649f924544f4a2cea5b9dfb9cc0a2bd8f3ba70
f4ba2e7f42960465c9eade118630f9c832fe84ef548529979d0d6ea079f9d5c4
0e396b098fc509448d26de3cb484b0334afacaba371b52c37c120a5623170c1d
0a39348a151c9fb8aab1049f52cf0c08c77144af314259a90848f3dc62e5831f
ac08720b1c813506f1db1e7940def52dc46c97d6363cda0ff7e2258e2637d2e0
9f26099bbfeac78819198b78374d2424537fe549a2ab3dddaf5f7fdb739c3921
064b04f6ffcfeb5544db533179038e11d0cc622992bc6d0600584d4068a2891d
c748c9c16be32c2a08e96caa2ddec4ddd1a2ab3b018a0b0f166a15ac870a30c8
0cc897dbf15af7e8c2915b3616f237a6646e43c665f7569a5ed1850ad8cd0540
06d389568db55393e780e752ace8f06b70f1e99d86b9445d9c1a7a6476bcbf48
4400a58e5a5a73d2c20d630a9985bbf4c691abb61ee4515aa64a727e7bac4a5e
d7bb5f767c7dcf0035904231283d92445863702a995e792bde1d5ac7dd624898
7b9fe4b0a6f1837ce4fbaa032ff4671a86be8c7e4f9be3718212ead0a6f1b429
88863bf80af17a9814f1ffbed6c81e7f59de5b8c71b9f571fc556cc56aee22be
1b57d48f8ca76a379847c67d0ceb43ead101355e541a57c254ae814f058a0361
92f49d96236c88428e5f54dafefd1a5b8ca12d85cf3833d38d816c6e0e205143
f33e353c471abc978d28d1ac89a724d5aab3e7c48015c5cd3a6f31c258cef131
2574e692c6e495a2a8efbee785a9fe1c727379ea1fdc5b492a83a4aff7b3945a
ef503a95dc52b21474172bb54054b106342f2bde6bc38ad166c1a5c6d88685b8
067f529741b36991352d5df1291b9e3c746a71e2bda796fdddac29d0e2f3fadf
d1f0fd33da75bc6151d3ee27f6199e76c3b9e872fb63b54ad78b0fbe2be84f10
d7e48339c6e63364507074addc5a2bd8c4be5848c291bdb2740d3aa325c35039
6ce28e086eecdd6256f48fb7947b84e85759b1c7e6dd91223e3f828e4253a7ec
6d987ad61bd2179c229a20e8d97e6158cb0be734227698b4695c784c463cac3e
a7d538056d5062a895f8ae64549bd58484a60363ab81bc43e6fde0ee12477051
b53c970f063df2f0ff2fd655b7f81029be545cc841f7321d31304eeba210fdf8
fdad7e1bc8accd4d990c058b30817e85e2c5695ab92c1e129ac7471f338fdd39
4ede16071450c19061e07c135cbe87f01260b36206cbc169c85b9dda26fb3dff
5e7d68fd51a573402dbcc1dc7f49a1cb9c34100b9b3d0bb8b8639c69c7d47490
ab83c8918ad03ae62eee43165e452f854d8d4132186c21f742ee4a3cc614515a
dc7c08940838538503f5c4d5781e984cad93cf7a8d17a68d678b3466afbae362
055d5b6edb0007b59231d3040dbfec8b9782b39c391116f2037e218bfaba46c5
2c56180aeef241d918f214b0b6480b7382875ad9dace4496c3682ea2a697b5fe
43b107d93e1976b2540dbfda2ae223bc1a84d65e0d6702513b8cc442a25fb983
aadfa492d09e3dfd991f9f47470bb73369f634dd50dab26d129c3ba096ad7971
1f0ee4419c1226eb8da42674b2cf77e8f4a3f76ce9e9e249b4d1fcc778ef318d
bd6778556c0f9878ebe6e8324916d78280f23f7e3921b29b42bba6ca2d780399
ca4ed3cb2d036c9bed80b235809198422135e2d842c8f53a4dd59fe0bed889d4
7840164024b1f668cc566978d431eb2a07a20ed06e575551e1b030db1350e94c
929a028a5dc25340e3434f2250e3f49de171bb850875d280050e495544ba71b7
1ea36c2937ad6593e2b5bca28bc38e59cea91f26cd1ca8aa4bd9fbc1c605ae46
ae3f559b3a6ebf89ff569ff365c3cba4b4b91f665ffda397188fe23ea456c802
c47a8062844d404fab41a0fa83fd0dd66e4db51115f026197f4c89a1bf28246b
a9966ca2973b0f3afa43154896a56bfe2153dfaaa3ccd2ab011b7f91470cbdc0
4af7cfe1703de7040f4d7777b068769d4035377cc7664f406b5d69356aa33045
c4334a1e2ce602ea2b1ec666352d14b5996dad451a4cb886c66143dc25f8f1bc
f0ed253febc9733432eada35a6afc982749fa0ec680a881db06171ea37fa8338
1ec90a6afa2f269d9da07c8f302161e26c9a4c21c2560ced811bdf6be402d36a
e2f11f884351241e779a22f8b69a8e3eeaa676e7150143a66b3a92d4dace9f4f
9b61e3f7e0aa7656c818ecfb53303457d51e74e7ec89cf038c9a73f3834383e8
22d2f50c3a7775aa0e63b127a214db7490e488f7ee91782a90de32f4ab22601a
f7b190fcc6a292e42e2f8b69caace994b127e9f91532b6d8c3b7ce08f991d269
220bceeed7d4e6151523e63e41bcd27154fd3a7f7370c04b1258715413ec5f17
f51baa99e8e5cd59ac7af17daecd0e8926002403ab87a422e422a6fb1186b5bb
7db25faffedad247fd741b2461aa3b9612342142af10decefe00c00b37a667ad
7665fbc4085b5312bda690166245a93b
*/
// public
/* on-disk format
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3zsBGAc4qEvDJJMuaMOuZAGaBLLFDaRk/MLK5/dSvyzAMkY8qd9ZEEPNheufIyjGMJX08TfTixBCLu+k6holLoUs1dfL3IVC8OB3L+3QsehloZv0xhKzpZ2Gt2g/CmS9shm11aZGfwi2cS/DeQFqMdtUZqipTKdxoJXdyKaXQt1OnglqJuVJ1+cAl4hU0PGyIzWaQoiH4rp72de5GTcfRGNpBBQfqXWtkid1gr9imZGSS2z4nnxp4JA24q72mxQcUyWNmUKcggef6XUcsFCiwfq5dFbZOoeKnUIUS/pq2VfhqMTSG08yh3Y6QrMXJ+6TW52dQf7q586f2jHSBQq8qNwHTGoqbdRGViqdxh7pwLtk004WvzuQjgOleDn6bwPTSM2f8dwN0Fnt/CSb7b9ttBarRz9GRgkhFsBThgVO/DR08Ox+tuyWj8dFR+baEYz2MFpD82MrQWqwq6yPb8Zo35ICgCJEDGcEW1HvZJLOZQlQ7iKD2EnlSstjhKQ8wKfVCrr6cDI42zzKWhlzWZDyJJNVm6/SXGAk5mhrAlv4e3Dtfhxv17wtNRODqJ2INIFFC4L/PZ3tNsCVTISGj8HRapNBYYzFzMleFWlzsvjrEQD0E/wzAxYt8BJBLQCElwrwqY6IOuzCcxvPmXbMBoFi42s4H5xs48/NZVDP2mxmPBw== This is a comment string
*/
/* actual bytes (hex repr)
00000000: 00 00 00 07 73 73 68 2d 72 73 61 00 00 00 03 01 ....ssh-rsa.....
00000010: 00 01 00 00 02 01 00 b7 ce c0 46 01 ce 2a 12 f0 ..........F..*..
00000020: c9 24 cb 9a 30 eb 99 00 66 81 2c b1 43 69 19 3f .$..0...f.,.Ci.?
00000030: 30 b2 b9 fd d4 af cb 30 0c 91 8f 2a 77 d6 44 10 0......0...*w.D.
00000040: f3 61 7a e7 c8 ca 31 8c 25 7d 3c 4d f4 e2 c4 10 .az...1.%}<M....
00000050: 8b bb e9 3a 86 89 4b a1 4b 35 75 f2 f7 21 50 bc ...:..K.K5u..!P.
00000060: 38 1d cb fb 74 2c 7a 19 68 66 fd 31 84 ac e9 67 8...t,z.hf.1...g
00000070: 61 ad da 0f c2 99 2f 6c 86 6d 75 69 91 9f c2 2d a...../l.mui...-
00000080: 9c 4b f0 de 40 5a 8c 76 d5 19 aa 2a 53 29 dc 68 .K..@Z.v...*S).h
00000090: 25 77 72 29 a5 d0 b7 53 a7 82 5a 89 b9 52 75 f9 %wr)...S..Z..Ru.
000000a0: c0 25 e2 15 34 3c 6c 88 cd 66 90 a2 21 f8 ae 9e .%..4<l..f..!...
000000b0: f6 75 ee 46 4d c7 d1 18 da 41 05 07 ea 5d 6b 64 .u.FM....A...]kd
000000c0: 89 dd 60 af d8 a6 64 64 92 db 3e 27 9f 1a 78 24 ..`...dd..>'..x$
000000d0: 0d b8 ab bd a6 c5 07 14 c9 63 66 50 a7 20 81 e7 .........cfP. ..
000000e0: fa 5d 47 2c 14 28 b0 7e ae 5d 15 b6 4e a1 e2 a7 .]G,.(.~.]..N...
000000f0: 50 85 12 fe 9a b6 55 f8 6a 31 34 86 d3 cc a1 dd P.....U.j14.....
00000100: 8e 90 ac c5 c9 fb a4 d6 e7 67 50 7f ba b9 f3 a7 .........gP.....
00000110: f6 8c 74 81 42 af 2a 37 01 d3 1a 8a 9b 75 11 95 ..t.B.*7.....u..
00000120: 8a a7 71 87 ba 70 2e d9 34 d3 85 af ce e4 23 80 ..q..p..4.....#.
00000130: e9 5e 0e 7e 9b c0 f4 d2 33 67 fc 77 03 74 16 7b .^.~....3g.w.t.{
00000140: 7f 09 26 fb 6f db 6d 05 aa d1 cf d1 91 82 48 45 ..&.o.m.......HE
00000150: b0 14 e1 81 53 bf 0d 1d 3c 3b 1f ad bb 25 a3 f1 ....S...<;...%..
00000160: d1 51 f9 b6 84 63 3d 8c 16 90 fc d8 ca d0 5a ac .Q...c=.......Z.
00000170: 2a eb 23 db f1 9a 37 e4 80 a0 08 91 03 19 c1 16 *.#...7.........
00000180: d4 7b d9 24 b3 99 42 54 3b 88 a0 f6 12 79 52 b2 .{.$..BT;....yR.
00000190: d8 e1 29 0f 30 29 f5 42 ae be 9c 0c 8e 36 cf 32 ..).0).B.....6.2
000001a0: 96 86 5c d6 64 3c 89 24 d5 66 eb f4 97 18 09 39 ..\.d<.$.f.....9
000001b0: 9a 1a c0 96 fe 1e dc 3b 5f 87 1b f5 ef 0b 4d 44 .......;_.....MD
000001c0: e0 ea 27 62 0d 20 51 42 e0 bf cf 67 7b 4d b0 25 ..'b. QB...g{M.%
000001d0: 53 21 21 a3 f0 74 5a a4 d0 58 63 31 73 32 57 85 S!!..tZ..Xc1s2W.
000001e0: 5a 5c ec be 3a c4 40 3d 04 ff 0c c0 c5 8b 7c 04 Z\..:.@=......|.
000001f0: 90 4b 40 21 25 c2 bc 2a 63 a2 0e bb 30 9c c6 f3 .K@!%..*c...0...
00000200: e6 5d b3 01 a0 58 b8 da ce 07 e7 1b 38 f3 f3 59 .]...X......8..Y
00000210: 54 33 f6 9b 19 8f 07 T3.....
//
00000007 7
7373682d727361 "ssh-rsa"
00000003 3
010001 65537
00000201 513
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4af ((32*16) + 1) bytes (513 bytes) modulus (ASN.1 format)
cb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc299
2f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7
d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab6
55f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0
f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a
37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1e
dc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2
bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07
*/ */


func main() { func main() {

View File

@ -87,9 +87,18 @@ ANNOTATED HEX:
DECRYPTED 4.0.1: DECRYPTED 4.0.1:
(...) (...)
4.0.1 000000a0 (160) 4.0.1 000000a0 (160)
4.0.1.0 4.0.1.0 f890d89a (4170242202)
4.0.1.1 4.0.1.1 f890d89a (4170242202)
4.0.1.2 4.0.1.2 -
4.0.2.3 4.0.1.2.0 0000000b (11)
4.0.2.4 4.0.1.2.0.0 7373682d65643235353139 ("ssh-ed25519")
4.0.2.5 4.0.1.2.1 00000020 (32)
4.0.1.2.1.0 (bytes)
bfa2031aa5463113e40e16896af503c5299ead76b09cb63846f41cc4de1740f6
4.0.1.3 00000040 (64)
4.0.1.3.0 (bytes)
ce6e2b8d638c9d5219dff455af1a90d0a5b72694cfcedfb93bc1e1b1816dee98
bfa2031aa5463113e40e16896af503c5299ead76b09cb63846f41cc4de1740f6
4.0.1.4 00000012 (18)
4.0.1.4.0 5468697320697320612074657374206b6579 ("This is a test key")
4.0.1.5 0102030405060708090a0b ([1 2 3 4 5 6 7 8 9 10 11], 11 bytes)

View File

@ -253,22 +253,14 @@ ANNOTATED HEX:
4.0.0.1.0 010001 (65537) 4.0.0.1.0 010001 (65537)
4.0.0.2 00000201 (513) 4.0.0.2 00000201 (513)
4.0.0.2.0 (bytes) 4.0.0.2.0 (bytes)
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4af 00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4afcb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
cb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689 4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc2992f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc299 b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
2f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0 0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab655f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7 2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5 0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab6 f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1edc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
55f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af 5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0
f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a
37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1e
dc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2
bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07 07
4.0.1 00000750 (1872) 4.0.1 00000750 (1872)
4.0.1.0 - 4.0.1.8 (AES256-CTR encrypted block) (bytes) 4.0.1.0 - 4.0.1.8 (AES256-CTR encrypted block) (bytes)
@ -303,7 +295,58 @@ ANNOTATED HEX:
f51baa99e8e5cd59ac7af17daecd0e8926002403ab87a422e422a6fb1186b5bb7db25faffedad247fd741b2461aa3b9612342142af10decefe00c00b37a667ad f51baa99e8e5cd59ac7af17daecd0e8926002403ab87a422e422a6fb1186b5bb7db25faffedad247fd741b2461aa3b9612342142af10decefe00c00b37a667ad
7665fbc4085b5312bda690166245a93b 7665fbc4085b5312bda690166245a93b



DECRYPTED 4.0.1: DECRYPTED 4.0.1:
(...) (...)
4.0.1 00000750 (1872) 4.0.1 00000750 (1872)
4.0.1.0 4.0.1.0 0d98bd61 (228113761)
4.0.1.1 0d98bd61 (228113761)
4.0.1.2 -
4.0.1.2.0 00000007 (7)
4.0.1.2.0.0 7373682d727361 ("ssh-rsa")
4.0.1.2.1 00000201 (513)
4.0.1.2.1.0 (bytes)
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4afcb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc2992f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab655f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1edc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07
4.0.1.2.2 00000003 (3)
4.0.1.2.2.0 010001 (65537)
4.0.1.3 00000200 (512)
4.0.1.3.0 (bytes)
499f2c705e04bfe17a4476d27e5e1ddfd8c335f63ac22f748754f02183440f6da93f3f86429261663e0bddfda69d4c2f705d0bbe7dd31a8941bf5672e29844a1
e0670970c6f2a98b76f85b26fafedb59c49786b8df7eaeeb86171fd579fe8df0eadd2536a4244a0332d5a9ad3eb8340c930464153e82b4ffad4f647a7ba808e3
854450f806b60e0b670fc99cb6b58786497d4c199e7750ee5089934eef25f46512394955c487e10744ebdb9a00951c8095b024d4ce75f1da3146b5b3447169f5
9e23d40685438bc7bcad1173927a389a0903ba111a46809d123b3432197cca8fc0c27816fbf215c2b7c584b94f37c9ed8a8e815942effdcf54757268afe58fd7
00cdcf6a98a20950617b0624aa835d95e27d7afcdee70c397ca1b6aa04735e6d5c5e01bfff2174cf562d36842624490e12ca8142595d52567494f38b2124012c
acacb2564e21c845eb94f5d6ebf6f39066e1fa04b318174e6f9994823ba4d9ef2c28b37cb3ea05fa3cad7200898394276835523e4e416054f23db0eb732211d3
a11ea551390ae8d58d69e14664e0e20f2bf0ccd24d260b832a94144f5801ea7cdbb2436f21ba2dbaecbcd573f24c5e0d43fd26b4ae6764e138ddaf4775ac0163
e45727c10027f716cbe3cc70fff73441bb2538e5426a1a5638b448a7bde968041ec2184ef67b0da60070297cd73deeefebd1951611c7a776c956e18e5f163a21
4.0.1.4 00000100 (256)
4.0.1.4.0 (bytes)
0ae2e1cf2455a0d82272e6a42bbba83eb765496e5a33e13b8c94756d8c32f7d7505fd997bdd5ec08c59bf8d1d659d1df02bec669ebb5aaaf5db1ec70ce2f2a6b
3a17b7b1fce3adc6203c2905cd652d7622065dd011ae33894467c6dca3643952b0caedff9bc78ac40408074027566ee4c4751ad3ff452a2781af8b5c2c9bf09b
34ee5e6201330b4bc381af766798667c5b9ad0733c19f4ef475fd264655e030553f2f2f8de59c2aee74b9dd6720e3108143dfedd41cf4bc11de2b9a9f40faec7
2a52312abee4c6155acfee9384a16348c715346ebe693895fe6d2348d4dedb0a137c487185ff949c209115b9c8a106329991f049e8430c7ba60dd5408d72ac98
4.0.1.5 00000101 (257)
4.0.1.5.0 (bytes)
00e50b65ba6ae4cb29ae66129c3e41ffeba36cd6ecbaa7045ff90cea71d09bc056b0b9134dc5754c49da1fe8ab169cd149eedaeccf4913d915f4f241c5fd86c7
7511e0c261c344600a84cce78e8cf493e492844cb82c42ab6d1246a53e5cf50ad4759c2a5c09d53b1c5c3b449328eea01434d6e537b3a513928dfaddf0a72728
23899b8d795220cb3344ab8d0e846e1e40ffdfb5c719262c2b527a890a51faabcf10904699135f7b997487f4b48d4490ad80fc25b346fa0bb587f09295bf0f71
ac10a8086867d4bad00a0c27a6456f08e0c2bf8caed8768f0366a2440428180a292617af61feabab9a7075b8bc21209a5439bbfe3613917071fee74a8d5d80fe
99
4.0.1.6 00000101 (257)
4.0.1.6.0 (bytes)
00cd7077659fad983104bcc7dc526242b9ea52cea40e923df771ac2a28e377f2b9231a58c2448c6b8d17fe83571ef6bdbbc11f3d4ab4254ea859684b8772911f
9c6f355479053e3e3d3a6ecce13a016908298ca3f8b628d2111749a3627628eb05844f546795a5067d39b1d304e19cc6fc1be00a6164ea33e4abbc87f5683227
1d825c868c5ccda3775b037711e99436f96c53f3780b985084e1d84a458c687ab0938a09bf6f9b3ffec41ed02fd5b27572c7d180039e405a559b62fc08f804b1
9f043dba4c6f7565b1c72759f4b932d4f93d4f41da91b1b146f29854a1008341e4760bdd4987097ec4a6551ab96e099a04a38d6a893b533db185abb55736419e
9f
4.0.1.7 00000018 (24)
4.0.1.7.0 54686973206973206120636f6d6d656e7420737472696e67 ("This is a comment string")
4.0.1.8 010203 ([1 2 3], 3 bytes)

View File

@ -16,11 +16,69 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
############################################################################# #############################################################################


The following uses the bcrypt encryption. The passphrase is "test". The following uses the bcrypt encryption (4096-bit). The passphrase is "test".


PEM: PEM:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3zsBGAc4qEvDJJMuaMOuZAGaBLLFDaRk/MLK5/dSvyzAMkY8qd9ZEEPNheufIyjGMJX08TfTixBCLu+k6holLoUs1dfL3IVC8OB3L+3QsehloZv0xhKzpZ2Gt2g/CmS9shm11aZGfwi2cS/DeQFqMdtUZqipTKdxoJXdyKaXQt1OnglqJuVJ1+cAl4hU0PGyIzWaQoiH4rp72de5GTcfRGNpBBQfqXWtkid1gr9imZGSS2z4nnxp4JA24q72mxQcUyWNmUKcggef6XUcsFCiwfq5dFbZOoeKnUIUS/pq2VfhqMTSG08yh3Y6QrMXJ+6TW52dQf7q586f2jHSBQq8qNwHTGoqbdRGViqdxh7pwLtk004WvzuQjgOleDn6bwPTSM2f8dwN0Fnt/CSb7b9ttBarRz9GRgkhFsBThgVO/DR08Ox+tuyWj8dFR+baEYz2MFpD82MrQWqwq6yPb8Zo35ICgCJEDGcEW1HvZJLOZQlQ7iKD2EnlSstjhKQ8wKfVCrr6cDI42zzKWhlzWZDyJJNVm6/SXGAk5mhrAlv4e3Dtfhxv17wtNRODqJ2INIFFC4L/PZ3tNsCVTISGj8HRapNBYYzFzMleFWlzsvjrEQD0E/wzAxYt8BJBLQCElwrwqY6IOuzCcxvPmXbMBoFi42s4H5xs48/NZVDP2mxmPBw== This is a comment string ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3zsBGAc4qEvDJJMuaMOuZAGaBLLFDaRk/MLK5/dSvyzAMkY8qd9ZEEPNheufIyjGMJX08TfTixBCLu+k6holLoUs1dfL3IVC8OB3L+3QsehloZv0xhKzpZ2Gt2g/CmS9shm11aZGfwi2cS/DeQFqMdtUZqipTKdxoJXdyKaXQt1OnglqJuVJ1+cAl4hU0PGyIzWaQoiH4rp72de5GTcfRGNpBBQfqXWtkid1gr9imZGSS2z4nnxp4JA24q72mxQcUyWNmUKcggef6XUcsFCiwfq5dFbZOoeKnUIUS/pq2VfhqMTSG08yh3Y6QrMXJ+6TW52dQf7q586f2jHSBQq8qNwHTGoqbdRGViqdxh7pwLtk004WvzuQjgOleDn6bwPTSM2f8dwN0Fnt/CSb7b9ttBarRz9GRgkhFsBThgVO/DR08Ox+tuyWj8dFR+baEYz2MFpD82MrQWqwq6yPb8Zo35ICgCJEDGcEW1HvZJLOZQlQ7iKD2EnlSstjhKQ8wKfVCrr6cDI42zzKWhlzWZDyJJNVm6/SXGAk5mhrAlv4e3Dtfhxv17wtNRODqJ2INIFFC4L/PZ3tNsCVTISGj8HRapNBYYzFzMleFWlzsvjrEQD0E/wzAxYt8BJBLQCElwrwqY6IOuzCcxvPmXbMBoFi42s4H5xs48/NZVDP2mxmPBw== This is a comment string


HEX: HEX:
00000000: 0000 0007 7373 682d 7273 6100 0000 0301 ....ssh-rsa.....
00000010: 0001 0000 0201 00b7 cec0 4601 ce2a 12f0 ..........F..*..
00000020: c924 cb9a 30eb 9900 6681 2cb1 4369 193f .$..0...f.,.Ci.?
00000030: 30b2 b9fd d4af cb30 0c91 8f2a 77d6 4410 0......0...*w.D.
00000040: f361 7ae7 c8ca 318c 257d 3c4d f4e2 c410 .az...1.%}<M....
00000050: 8bbb e93a 8689 4ba1 4b35 75f2 f721 50bc ...:..K.K5u..!P.
00000060: 381d cbfb 742c 7a19 6866 fd31 84ac e967 8...t,z.hf.1...g
00000070: 61ad da0f c299 2f6c 866d 7569 919f c22d a...../l.mui...-
00000080: 9c4b f0de 405a 8c76 d519 aa2a 5329 dc68 .K..@Z.v...*S).h
00000090: 2577 7229 a5d0 b753 a782 5a89 b952 75f9 %wr)...S..Z..Ru.
000000a0: c025 e215 343c 6c88 cd66 90a2 21f8 ae9e .%..4<l..f..!...
000000b0: f675 ee46 4dc7 d118 da41 0507 ea5d 6b64 .u.FM....A...]kd
000000c0: 89dd 60af d8a6 6464 92db 3e27 9f1a 7824 ..`...dd..>'..x$
000000d0: 0db8 abbd a6c5 0714 c963 6650 a720 81e7 .........cfP. ..
000000e0: fa5d 472c 1428 b07e ae5d 15b6 4ea1 e2a7 .]G,.(.~.]..N...
000000f0: 5085 12fe 9ab6 55f8 6a31 3486 d3cc a1dd P.....U.j14.....
00000100: 8e90 acc5 c9fb a4d6 e767 507f bab9 f3a7 .........gP.....
00000110: f68c 7481 42af 2a37 01d3 1a8a 9b75 1195 ..t.B.*7.....u..
00000120: 8aa7 7187 ba70 2ed9 34d3 85af cee4 2380 ..q..p..4.....#.
00000130: e95e 0e7e 9bc0 f4d2 3367 fc77 0374 167b .^.~....3g.w.t.{
00000140: 7f09 26fb 6fdb 6d05 aad1 cfd1 9182 4845 ..&.o.m.......HE
00000150: b014 e181 53bf 0d1d 3c3b 1fad bb25 a3f1 ....S...<;...%..
00000160: d151 f9b6 8463 3d8c 1690 fcd8 cad0 5aac .Q...c=.......Z.
00000170: 2aeb 23db f19a 37e4 80a0 0891 0319 c116 *.#...7.........
00000180: d47b d924 b399 4254 3b88 a0f6 1279 52b2 .{.$..BT;....yR.
00000190: d8e1 290f 3029 f542 aebe 9c0c 8e36 cf32 ..).0).B.....6.2
000001a0: 9686 5cd6 643c 8924 d566 ebf4 9718 0939 ..\.d<.$.f.....9
000001b0: 9a1a c096 fe1e dc3b 5f87 1bf5 ef0b 4d44 .......;_.....MD
000001c0: e0ea 2762 0d20 5142 e0bf cf67 7b4d b025 ..'b. QB...g{M.%
000001d0: 5321 21a3 f074 5aa4 d058 6331 7332 5785 S!!..tZ..Xc1s2W.
000001e0: 5a5c ecbe 3ac4 403d 04ff 0cc0 c58b 7c04 Z\..:.@=......|.
000001f0: 904b 4021 25c2 bc2a 63a2 0ebb 309c c6f3 .K@!%..*c...0...
00000200: e65d b301 a058 b8da ce07 e71b 38f3 f359 .]...X......8..Y
00000210: 5433 f69b 198f 07 T3.....



ANNOTATED HEX: ANNOTATED HEX:
0 00000007 (7)
0.0 7373682d727361 ("ssh-rsa")
1 00000003 (3)
1.0 010001 (65537)
2 00000201 (513)
2.0 (bytes)
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4af
cb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc299
2f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7
d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab6
55f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0
f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a
37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1e
dc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2
bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07

View File

@ -343,4 +343,4 @@ ANNOTATED HEX:
9f 9f
4.0.1.7 00000018 (24) 4.0.1.7 00000018 (24)
4.0.1.7.0 54686973206973206120636f6d6d656e7420737472696e67 ("This is a comment string") 4.0.1.7.0 54686973206973206120636f6d6d656e7420737472696e67 ("This is a comment string")
4.0.1.8 010203 (padding) 4.0.1.8 010203 ([1 2 3], 3 bytes)

View File

@ -16,3 +16,72 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
############################################################################# #############################################################################


The following is a plaintext pubkey (no passphrase provided) (4096-bit).

Keys in the "PEM" (.pub) format are prefixed with the key type string and suffixed with the comment string.

All length ints are uint32, network-byte order.

PEM:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3zsBGAc4qEvDJJMuaMOuZAGaBLLFDaRk/MLK5/dSvyzAMkY8qd9ZEEPNheufIyjGMJX08TfTixBCLu+k6holLoUs1dfL3IVC8OB3L+3QsehloZv0xhKzpZ2Gt2g/CmS9shm11aZGfwi2cS/DeQFqMdtUZqipTKdxoJXdyKaXQt1OnglqJuVJ1+cAl4hU0PGyIzWaQoiH4rp72de5GTcfRGNpBBQfqXWtkid1gr9imZGSS2z4nnxp4JA24q72mxQcUyWNmUKcggef6XUcsFCiwfq5dFbZOoeKnUIUS/pq2VfhqMTSG08yh3Y6QrMXJ+6TW52dQf7q586f2jHSBQq8qNwHTGoqbdRGViqdxh7pwLtk004WvzuQjgOleDn6bwPTSM2f8dwN0Fnt/CSb7b9ttBarRz9GRgkhFsBThgVO/DR08Ox+tuyWj8dFR+baEYz2MFpD82MrQWqwq6yPb8Zo35ICgCJEDGcEW1HvZJLOZQlQ7iKD2EnlSstjhKQ8wKfVCrr6cDI42zzKWhlzWZDyJJNVm6/SXGAk5mhrAlv4e3Dtfhxv17wtNRODqJ2INIFFC4L/PZ3tNsCVTISGj8HRapNBYYzFzMleFWlzsvjrEQD0E/wzAxYt8BJBLQCElwrwqY6IOuzCcxvPmXbMBoFi42s4H5xs48/NZVDP2mxmPBw== This is a comment string

HEX:
00000000: 0000 0007 7373 682d 7273 6100 0000 0301 ....ssh-rsa.....
00000010: 0001 0000 0201 00b7 cec0 4601 ce2a 12f0 ..........F..*..
00000020: c924 cb9a 30eb 9900 6681 2cb1 4369 193f .$..0...f.,.Ci.?
00000030: 30b2 b9fd d4af cb30 0c91 8f2a 77d6 4410 0......0...*w.D.
00000040: f361 7ae7 c8ca 318c 257d 3c4d f4e2 c410 .az...1.%}<M....
00000050: 8bbb e93a 8689 4ba1 4b35 75f2 f721 50bc ...:..K.K5u..!P.
00000060: 381d cbfb 742c 7a19 6866 fd31 84ac e967 8...t,z.hf.1...g
00000070: 61ad da0f c299 2f6c 866d 7569 919f c22d a...../l.mui...-
00000080: 9c4b f0de 405a 8c76 d519 aa2a 5329 dc68 .K..@Z.v...*S).h
00000090: 2577 7229 a5d0 b753 a782 5a89 b952 75f9 %wr)...S..Z..Ru.
000000a0: c025 e215 343c 6c88 cd66 90a2 21f8 ae9e .%..4<l..f..!...
000000b0: f675 ee46 4dc7 d118 da41 0507 ea5d 6b64 .u.FM....A...]kd
000000c0: 89dd 60af d8a6 6464 92db 3e27 9f1a 7824 ..`...dd..>'..x$
000000d0: 0db8 abbd a6c5 0714 c963 6650 a720 81e7 .........cfP. ..
000000e0: fa5d 472c 1428 b07e ae5d 15b6 4ea1 e2a7 .]G,.(.~.]..N...
000000f0: 5085 12fe 9ab6 55f8 6a31 3486 d3cc a1dd P.....U.j14.....
00000100: 8e90 acc5 c9fb a4d6 e767 507f bab9 f3a7 .........gP.....
00000110: f68c 7481 42af 2a37 01d3 1a8a 9b75 1195 ..t.B.*7.....u..
00000120: 8aa7 7187 ba70 2ed9 34d3 85af cee4 2380 ..q..p..4.....#.
00000130: e95e 0e7e 9bc0 f4d2 3367 fc77 0374 167b .^.~....3g.w.t.{
00000140: 7f09 26fb 6fdb 6d05 aad1 cfd1 9182 4845 ..&.o.m.......HE
00000150: b014 e181 53bf 0d1d 3c3b 1fad bb25 a3f1 ....S...<;...%..
00000160: d151 f9b6 8463 3d8c 1690 fcd8 cad0 5aac .Q...c=.......Z.
00000170: 2aeb 23db f19a 37e4 80a0 0891 0319 c116 *.#...7.........
00000180: d47b d924 b399 4254 3b88 a0f6 1279 52b2 .{.$..BT;....yR.
00000190: d8e1 290f 3029 f542 aebe 9c0c 8e36 cf32 ..).0).B.....6.2
000001a0: 9686 5cd6 643c 8924 d566 ebf4 9718 0939 ..\.d<.$.f.....9
000001b0: 9a1a c096 fe1e dc3b 5f87 1bf5 ef0b 4d44 .......;_.....MD
000001c0: e0ea 2762 0d20 5142 e0bf cf67 7b4d b025 ..'b. QB...g{M.%
000001d0: 5321 21a3 f074 5aa4 d058 6331 7332 5785 S!!..tZ..Xc1s2W.
000001e0: 5a5c ecbe 3ac4 403d 04ff 0cc0 c58b 7c04 Z\..:.@=......|.
000001f0: 904b 4021 25c2 bc2a 63a2 0ebb 309c c6f3 .K@!%..*c...0...
00000200: e65d b301 a058 b8da ce07 e71b 38f3 f359 .]...X......8..Y
00000210: 5433 f69b 198f 07 T3.....

ANNOTATED HEX:
0 00000007 (7)
0.0 7373682d727361 ("ssh-rsa")
1 00000003 (3)
1.1 010001 (65537)
2 00000201 (513)
2.0 (bytes)
00b7cec04601ce2a12f0c924cb9a30eb990066812cb14369193f30b2b9fdd4af
cb300c918f2a77d64410f3617ae7c8ca318c257d3c4df4e2c4108bbbe93a8689
4ba14b3575f2f72150bc381dcbfb742c7a196866fd3184ace96761adda0fc299
2f6c866d7569919fc22d9c4bf0de405a8c76d519aa2a5329dc6825777229a5d0
b753a7825a89b95275f9c025e215343c6c88cd6690a221f8ae9ef675ee464dc7
d118da410507ea5d6b6489dd60afd8a6646492db3e279f1a78240db8abbda6c5
0714c9636650a72081e7fa5d472c1428b07eae5d15b64ea1e2a7508512fe9ab6
55f86a313486d3cca1dd8e90acc5c9fba4d6e767507fbab9f3a7f68c748142af
2a3701d31a8a9b7511958aa77187ba702ed934d385afcee42380e95e0e7e9bc0
f4d23367fc770374167b7f0926fb6fdb6d05aad1cfd191824845b014e18153bf
0d1d3c3b1fadbb25a3f1d151f9b684633d8c1690fcd8cad05aac2aeb23dbf19a
37e480a008910319c116d47bd924b39942543b88a0f6127952b2d8e1290f3029
f542aebe9c0c8e36cf3296865cd6643c8924d566ebf4971809399a1ac096fe1e
dc3b5f871bf5ef0b4d44e0ea27620d205142e0bfcf677b4db025532121a3f074
5aa4d0586331733257855a5cecbe3ac4403d04ff0cc0c58b7c04904b402125c2
bc2a63a20ebb309cc6f3e65db301a058b8dace07e71b38f3f3595433f69b198f
07

View File

@ -35,7 +35,7 @@ func (k *SSHPrivKey) generateRsa() error {
} else { } else {
k.Key = sk // See https://golang.org/pkg/crypto/rsa/#PrivateKey k.Key = sk // See https://golang.org/pkg/crypto/rsa/#PrivateKey
k.PublicKey.KeyType = KeyRsa k.PublicKey.KeyType = KeyRsa
k.PublicKey.Key = k.Key.PublicKey k.PublicKey.Key = sk.PublicKey
} }
return nil return nil
} }

View File

@ -31,14 +31,14 @@ type EncryptedSSHKeyV1 struct {
Passphrase []byte Passphrase []byte
} }


// SSHEncryptionKey contains the PublicKey and PrivateKey bytes (as derived by KDF, different from the actual SSH keypair), // SSHCrypt contains the encryption object Stream, the cipher object Cipher, the ephemeral salt (CryptSalt), and the ephemeral key (CryptKey).
// the Cipher, and the stream. // the Cipher, and the stream.
type SSHCrypt struct { type SSHCrypt struct {
Stream cipher.Stream Stream cipher.Stream
Cipher cipher.Block Cipher cipher.Block
CryptSalt []byte PrivateKey []byte // encryption key
PrivateKey []byte CryptSalt []byte // ephemeral salt
CryptKey []byte CryptKey []byte // ephemeral key (not really used)
} }


// SSHKDFOpts contains a set of KDF options. // SSHKDFOpts contains a set of KDF options.
@ -56,7 +56,6 @@ type SSHKeyV1 struct {
KDFName string KDFName string
CipherName string CipherName string
KeySize uint32 KeySize uint32
BlockSize uint32
Keys []SSHPrivKey // 1 by default. Keys []SSHPrivKey // 1 by default.
Buffer bytes.Buffer Buffer bytes.Buffer
} }
@ -71,6 +70,7 @@ type SSHPubKey struct {
type SSHPrivKey struct { type SSHPrivKey struct {
PublicKey *SSHPubKey PublicKey *SSHPubKey
BitSize uint32 BitSize uint32
BlockSize int
Key interface{} Key interface{}
// ED25519 keys are actually "sk + pk", where sk is the secret key and pk is the pubkey. // ED25519 keys are actually "sk + pk", where sk is the secret key and pk is the pubkey.
// We store that here. // We store that here.