Skip to content

Commit 13af276

Browse files
stevenroosefjl
authored andcommittedJun 8, 2018
cmd/ethkey: add command to change key passphrase (ethereum#16516)
This change introduces ethkey changepassphrase <keyfile> to change the passphrase of a key file.
1 parent ea06da0 commit 13af276

File tree

6 files changed

+100
-19
lines changed

6 files changed

+100
-19
lines changed
 

‎cmd/ethkey/changepassphrase.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"strings"
7+
8+
"github.com/ethereum/go-ethereum/accounts/keystore"
9+
"github.com/ethereum/go-ethereum/cmd/utils"
10+
"gopkg.in/urfave/cli.v1"
11+
)
12+
13+
var newPassphraseFlag = cli.StringFlag{
14+
Name: "newpasswordfile",
15+
Usage: "the file that contains the new passphrase for the keyfile",
16+
}
17+
18+
var commandChangePassphrase = cli.Command{
19+
Name: "changepassphrase",
20+
Usage: "change the passphrase on a keyfile",
21+
ArgsUsage: "<keyfile>",
22+
Description: `
23+
Change the passphrase of a keyfile.`,
24+
Flags: []cli.Flag{
25+
passphraseFlag,
26+
newPassphraseFlag,
27+
},
28+
Action: func(ctx *cli.Context) error {
29+
keyfilepath := ctx.Args().First()
30+
31+
// Read key from file.
32+
keyjson, err := ioutil.ReadFile(keyfilepath)
33+
if err != nil {
34+
utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err)
35+
}
36+
37+
// Decrypt key with passphrase.
38+
passphrase := getPassphrase(ctx)
39+
key, err := keystore.DecryptKey(keyjson, passphrase)
40+
if err != nil {
41+
utils.Fatalf("Error decrypting key: %v", err)
42+
}
43+
44+
// Get a new passphrase.
45+
fmt.Println("Please provide a new passphrase")
46+
var newPhrase string
47+
if passFile := ctx.String(newPassphraseFlag.Name); passFile != "" {
48+
content, err := ioutil.ReadFile(passFile)
49+
if err != nil {
50+
utils.Fatalf("Failed to read new passphrase file '%s': %v", passFile, err)
51+
}
52+
newPhrase = strings.TrimRight(string(content), "\r\n")
53+
} else {
54+
newPhrase = promptPassphrase(true)
55+
}
56+
57+
// Encrypt the key with the new passphrase.
58+
newJson, err := keystore.EncryptKey(key, newPhrase, keystore.StandardScryptN, keystore.StandardScryptP)
59+
if err != nil {
60+
utils.Fatalf("Error encrypting with new passphrase: %v", err)
61+
}
62+
63+
// Then write the new keyfile in place of the old one.
64+
if err := ioutil.WriteFile(keyfilepath, newJson, 600); err != nil {
65+
utils.Fatalf("Error writing new keyfile to disk: %v", err)
66+
}
67+
68+
// Don't print anything. Just return successfully,
69+
// producing a positive exit code.
70+
return nil
71+
},
72+
}

‎cmd/ethkey/generate.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ If you want to encrypt an existing private key, it can be specified by setting
9090
}
9191

9292
// Encrypt key with passphrase.
93-
passphrase := getPassPhrase(ctx, true)
93+
passphrase := promptPassphrase(true)
9494
keyjson, err := keystore.EncryptKey(key, passphrase, keystore.StandardScryptN, keystore.StandardScryptP)
9595
if err != nil {
9696
utils.Fatalf("Error encrypting key: %v", err)

‎cmd/ethkey/inspect.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ make sure to use this feature with great caution!`,
6060
}
6161

6262
// Decrypt key with passphrase.
63-
passphrase := getPassPhrase(ctx, false)
63+
passphrase := getPassphrase(ctx)
6464
key, err := keystore.DecryptKey(keyjson, passphrase)
6565
if err != nil {
6666
utils.Fatalf("Error decrypting key: %v", err)

‎cmd/ethkey/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func init() {
3838
app.Commands = []cli.Command{
3939
commandGenerate,
4040
commandInspect,
41+
commandChangePassphrase,
4142
commandSignMessage,
4243
commandVerifyMessage,
4344
}

‎cmd/ethkey/message.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ To sign a message contained in a file, use the --msgfile flag.
6262
}
6363

6464
// Decrypt key with passphrase.
65-
passphrase := getPassPhrase(ctx, false)
65+
passphrase := getPassphrase(ctx)
6666
key, err := keystore.DecryptKey(keyjson, passphrase)
6767
if err != nil {
6868
utils.Fatalf("Error decrypting key: %v", err)

‎cmd/ethkey/utils.go

+24-16
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,14 @@ import (
2828
"gopkg.in/urfave/cli.v1"
2929
)
3030

31-
// getPassPhrase obtains a passphrase given by the user. It first checks the
32-
// --passphrase command line flag and ultimately prompts the user for a
33-
// passphrase.
34-
func getPassPhrase(ctx *cli.Context, confirmation bool) string {
35-
// Look for the --passphrase flag.
36-
passphraseFile := ctx.String(passphraseFlag.Name)
37-
if passphraseFile != "" {
38-
content, err := ioutil.ReadFile(passphraseFile)
39-
if err != nil {
40-
utils.Fatalf("Failed to read passphrase file '%s': %v",
41-
passphraseFile, err)
42-
}
43-
return strings.TrimRight(string(content), "\r\n")
44-
}
45-
46-
// Otherwise prompt the user for the passphrase.
31+
// promptPassphrase prompts the user for a passphrase. Set confirmation to true
32+
// to require the user to confirm the passphrase.
33+
func promptPassphrase(confirmation bool) string {
4734
passphrase, err := console.Stdin.PromptPassword("Passphrase: ")
4835
if err != nil {
4936
utils.Fatalf("Failed to read passphrase: %v", err)
5037
}
38+
5139
if confirmation {
5240
confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ")
5341
if err != nil {
@@ -57,9 +45,29 @@ func getPassPhrase(ctx *cli.Context, confirmation bool) string {
5745
utils.Fatalf("Passphrases do not match")
5846
}
5947
}
48+
6049
return passphrase
6150
}
6251

52+
// getPassphrase obtains a passphrase given by the user. It first checks the
53+
// --passfile command line flag and ultimately prompts the user for a
54+
// passphrase.
55+
func getPassphrase(ctx *cli.Context) string {
56+
// Look for the --passwordfile flag.
57+
passphraseFile := ctx.String(passphraseFlag.Name)
58+
if passphraseFile != "" {
59+
content, err := ioutil.ReadFile(passphraseFile)
60+
if err != nil {
61+
utils.Fatalf("Failed to read passphrase file '%s': %v",
62+
passphraseFile, err)
63+
}
64+
return strings.TrimRight(string(content), "\r\n")
65+
}
66+
67+
// Otherwise prompt the user for the passphrase.
68+
return promptPassphrase(false)
69+
}
70+
6371
// signHash is a helper function that calculates a hash for the given message
6472
// that can be safely used to calculate a signature from.
6573
//

0 commit comments

Comments
 (0)