diff --git a/dgraph/cmd/cert/info.go b/dgraph/cmd/cert/info.go index 2a27920f5ff..1b7a0b9df77 100644 --- a/dgraph/cmd/cert/info.go +++ b/dgraph/cmd/cert/info.go @@ -17,8 +17,8 @@ package cert import ( - "crypto/md5" "crypto/rsa" + "crypto/sha256" "encoding/hex" "fmt" "os" @@ -33,7 +33,7 @@ type certInfo struct { commonName string serialNumber string verifiedCA string - md5sum string + digest string expireDate time.Time hosts []string fileMode string @@ -76,10 +76,9 @@ func getFileInfo(file string) *certInfo { } if key, ok := cert.PublicKey.(*rsa.PublicKey); ok { - h := md5.Sum(key.N.Bytes()) - info.md5sum = fmt.Sprintf("%X", h[:]) + info.digest = getHexDigest(key.N.Bytes()) } else { - info.md5sum = "Invalid RSA public key" + info.digest = "Invalid RSA public key" } if file != defaultCACert { @@ -115,8 +114,7 @@ func getFileInfo(file string) *certInfo { info.err = err return &info } - h := md5.Sum(key.PublicKey.N.Bytes()) - info.md5sum = fmt.Sprintf("%X", h[:]) + info.digest = getHexDigest(key.PublicKey.N.Bytes()) default: info.err = fmt.Errorf("Unsupported file") @@ -125,6 +123,23 @@ func getFileInfo(file string) *certInfo { return &info } +// getHexDigest returns a SHA-256 hex digest broken up into 32-bit chunks +// so that they easier to compare visually +// e.g. 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5 +func getHexDigest(data []byte) string { + const groupSizeBytes = 4 + + digest := sha256.Sum256(data) + groups := len(digest) / groupSizeBytes + hex := fmt.Sprintf("%0*X", groupSizeBytes*2, digest[0:groupSizeBytes]) + for i := 1; i < groups; i++ { + hex += fmt.Sprintf(" %0*X", groupSizeBytes*2, + digest[i*groupSizeBytes:(i+1)*groupSizeBytes]) + } + + return hex +} + // getDirFiles walks dir and collects information about the files contained. // Returns the list of files, or an error otherwise. func getDirFiles(dir string) ([]*certInfo, error) { diff --git a/dgraph/cmd/cert/run.go b/dgraph/cmd/cert/run.go index 08395a263de..4c91b173902 100644 --- a/dgraph/cmd/cert/run.go +++ b/dgraph/cmd/cert/run.go @@ -121,21 +121,21 @@ func listCerts() error { } fmt.Printf("%s %s - %s\n", f.fileMode, f.fileName, f.commonName) if f.issuerName != "" { - fmt.Printf("%10s: %s\n", "Issuer", f.issuerName) + fmt.Printf("%14s: %s\n", "Issuer", f.issuerName) } if f.verifiedCA != "" { - fmt.Printf("%10s: %s\n", "CA Verify", f.verifiedCA) + fmt.Printf("%14s: %s\n", "CA Verify", f.verifiedCA) } if f.serialNumber != "" { - fmt.Printf("%10s: %s\n", "S/N", f.serialNumber) + fmt.Printf("%14s: %s\n", "S/N", f.serialNumber) } if !f.expireDate.IsZero() { - fmt.Printf("%10s: %x\n", "Expiration", f) + fmt.Printf("%14s: %x\n", "Expiration", f) } if f.hosts != nil { - fmt.Printf("%10s: %s\n", "Hosts", strings.Join(f.hosts, ", ")) + fmt.Printf("%14s: %s\n", "Hosts", strings.Join(f.hosts, ", ")) } - fmt.Printf("%10s: %s\n\n", "MD5 hash", f.md5sum) + fmt.Printf("%14s: %s\n\n", "SHA-256 Digest", f.digest) } return nil diff --git a/wiki/content/deploy/index.md b/wiki/content/deploy/index.md index eaed517eba6..a7047302366 100644 --- a/wiki/content/deploy/index.md +++ b/wiki/content/deploy/index.md @@ -1331,41 +1331,43 @@ Example of command output: ```sh -rw-r--r-- ca.crt - Dgraph Root CA certificate - Issuer: Dgraph Labs, Inc. - S/N: 3e468ac77ecd5017 -Expiration: 23 Sep 28 19:10 UTC - MD5 hash: 85B533D86B0DD689B9DBDAD6755B702F + Issuer: Dgraph Labs, Inc. + S/N: 043c4d8fdd347f06 + Expiration: 02 Apr 29 16:56 UTC +SHA-256 Digest: 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5 -r-------- ca.key - Dgraph Root CA key - MD5 hash: 85B533D86B0DD689B9DBDAD6755B702F +SHA-256 Digest: 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5 --rw-r--r-- client.srfrog.crt - Dgraph client certificate: srfrog - Issuer: Dgraph Labs, Inc. - CA Verify: PASSED - S/N: 55cedf3c8606d98e -Expiration: 25 Sep 23 19:25 UTC - MD5 hash: 445DCB276E29FA1000F79CAC376569BA +-rw-r--r-- client.admin.crt - Dgraph client certificate: admin + Issuer: Dgraph Labs, Inc. + CA Verify: PASSED + S/N: 297e4cb4f97c71f9 + Expiration: 03 Apr 24 17:29 UTC +SHA-256 Digest: D23EFB61 DE03C735 EB07B318 DB70D471 D3FE8556 B15D084C 62675857 788DF26C --rw------- client.srfrog.key - Dgraph Client key - MD5 hash: 445DCB276E29FA1000F79CAC376569BA +-rw------- client.admin.key - Dgraph Client key +SHA-256 Digest: D23EFB61 DE03C735 EB07B318 DB70D471 D3FE8556 B15D084C 62675857 788DF26C -rw-r--r-- node.crt - Dgraph Node certificate - Issuer: Dgraph Labs, Inc. - CA Verify: PASSED - S/N: 75aeb1ccd9a6f3fd -Expiration: 25 Sep 23 19:39 UTC - Hosts: localhost - MD5 hash: FA0FFC88F7AA654575CD48A493C3D65A + Issuer: Dgraph Labs, Inc. + CA Verify: PASSED + S/N: 795ff0e0146fdb2d + Expiration: 03 Apr 24 17:00 UTC + Hosts: 104.25.165.23, 2400:cb00:2048:1::6819:a417, localhost, dgraph.io +SHA-256 Digest: 7E243ED5 3286AE71 B9B4E26C 5B2293DA D3E7F336 1B1AFFA7 885E8767 B1A84D28 -rw------- node.key - Dgraph Node key - MD5 hash: FA0FFC88F7AA654575CD48A493C3D65A +SHA-256 Digest: 7E243ED5 3286AE71 B9B4E26C 5B2293DA D3E7F336 1B1AFFA7 885E8767 B1A84D28 ``` Important points: -* The cert/key pairs should always have matching MD5 hashes. Otherwise, the cert(s) must be regenerated. If the Root CA pair differ, all cert/key must be regenerated; the flag `--force` can help. +* The cert/key pairs should always have matching SHA-256 digests. Otherwise, the cert(s) must be + regenerated. If the Root CA pair differ, all cert/key must be regenerated; the flag `--force` + can help. * All certificates must pass Dgraph CA verification. -* All key files should have the least access permissions, specially the `ca.key`, but be readable. +* All key files should have the least access permissions, especially the `ca.key`, but be readable. * Key files won't be overwritten if they have limited access, even with `--force`. * Node certificates are only valid for the hosts listed. * Client certificates are only valid for the named client/user.