-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How is it possible to persist V3 .onion address? #38
Comments
Working off of the libtor example, observe these comments and changes.
|
I use this scheme based on ciehanski post. To create a key, func createKey(path string) (crypto.PrivateKey, error) {
path = strings.TrimSuffix(path, "hs_ed25519_secret_key")
err := os.MkdirAll(path, 0700)
if err != nil {
return nil, err
}
publicKey, secretKey, err := ed25519.GenerateKey(nil)
if err != nil {
return nil, err
}
onionAddress := encodePublicKey(publicKey)
expandedSecretKey := expandSecretKey(secretKey)
secretKeyFile := append([]byte("== ed25519v1-secret: type0 ==\x00\x00\x00"), expandedSecretKey[:]...)
secretKeyPath := filepath.Join(path, "/hs_ed25519_secret_key")
err = os.WriteFile(secretKeyPath, secretKeyFile, 0600)
if err != nil {
return nil, err
}
publicKeyFile := append([]byte("== ed25519v1-public: type0 ==\x00\x00\x00"), publicKey...)
publicKeyPath := filepath.Join(path, "/hs_ed25519_public_key")
err = os.WriteFile(publicKeyPath, publicKeyFile, 0600)
if err != nil {
os.Remove(secretKeyPath)
return nil, err
}
hostnameFile := []byte(onionAddress + ".onion\n")
hostnamePath := filepath.Join(path, "/hostname")
err = os.WriteFile(hostnamePath, hostnameFile, 0600)
if err != nil {
os.Remove(secretKeyPath)
os.Remove(publicKeyPath)
return nil, err
}
return bed25519.PrivateKey(expandedSecretKey[:]), nil
}
func expandSecretKey(secretKey ed25519.PrivateKey) [64]byte {
hash := sha512.Sum512(secretKey[:32])
hash[0] &= 248
hash[31] &= 127
hash[31] |= 64
return hash
}
func encodePublicKey(publicKey ed25519.PublicKey) string {
// checksum = H(".onion checksum" || pubkey || version)
var checksumBytes bytes.Buffer
checksumBytes.Write([]byte(".onion checksum"))
checksumBytes.Write([]byte(publicKey))
checksumBytes.Write([]byte{0x03})
checksum := sha3.Sum256(checksumBytes.Bytes())
// onion_address = base32(pubkey || checksum || version)
var onionAddressBytes bytes.Buffer
onionAddressBytes.Write([]byte(publicKey))
onionAddressBytes.Write([]byte(checksum[:2]))
onionAddressBytes.Write([]byte{0x03})
onionAddress := base32.StdEncoding.EncodeToString(onionAddressBytes.Bytes())
return strings.ToLower(onionAddress)
} to load a key func loadKey(path string) (crypto.PrivateKey, error) {
var key crypto.PrivateKey
if path != "" {
if !strings.HasSuffix(path, "hs_ed25519_secret_key") {
path = filepath.Join(path, "hs_ed25519_secret_key")
}
d, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to load the private key: %v", err)
}
d = bytes.TrimPrefix(d, []byte("== ed25519v1-secret: type0 ==\x00\x00\x00"))
key = bed25519.PrivateKey(d)
}
return key, nil
} The Then I give the key to the Tor process creator and it works upon restart. smooth. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I would like to keep my onion address static after I close the program and reopen it.
this is done with V2 addressed as described in issue #19, however it is not applicable with V3 addresses.
how do I make V3 addresses persistent after reopening the program?
The text was updated successfully, but these errors were encountered: