瀏覽代碼

x/crypto/ssh: Add FingerprintLegacyMD5 and FingerprintSHA256 methods

Implement a standards-compliant fingerprint format method (RFC 4716 section 4)
and a newer SHA256 fingerprint format method.

Fixes golang/go#12292

Change-Id: I4f3f8fc1d0a263cb3b0964d0078e69006a39d1a5
Reviewed-on: https://go-review.googlesource.com/32814
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Ryuzo Yamamoto 9 年之前
父節點
當前提交
ede567c8e0
共有 2 個文件被更改,包括 43 次插入0 次删除
  1. 25 0
      ssh/keys.go
  2. 18 0
      ssh/keys_test.go

+ 25 - 0
ssh/keys.go

@@ -10,10 +10,13 @@ import (
 	"crypto/dsa"
 	"crypto/ecdsa"
 	"crypto/elliptic"
+	"crypto/md5"
 	"crypto/rsa"
+	"crypto/sha256"
 	"crypto/x509"
 	"encoding/asn1"
 	"encoding/base64"
+	"encoding/hex"
 	"encoding/pem"
 	"errors"
 	"fmt"
@@ -878,3 +881,25 @@ func parseOpenSSHPrivateKey(key []byte) (*ed25519.PrivateKey, error) {
 	copy(pk, pk1.Priv)
 	return &pk, nil
 }
+
+// FingerprintLegacyMD5 returns the user presentation of the key's
+// fingerprint as described by RFC 4716 section 4.
+func FingerprintLegacyMD5(pubKey PublicKey) string {
+	md5sum := md5.Sum(pubKey.Marshal())
+	hexarray := make([]string, len(md5sum))
+	for i, c := range md5sum {
+		hexarray[i] = hex.EncodeToString([]byte{c})
+	}
+	return strings.Join(hexarray, ":")
+}
+
+// FingerprintSHA256 returns the user presentation of the key's
+// fingerprint as unpadded base64 encoded sha256 hash.
+// This format was introduced from OpenSSH 6.8.
+// https://www.openssh.com/txt/release-6.8
+// https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
+func FingerprintSHA256(pubKey PublicKey) string {
+	sha256sum := sha256.Sum256(pubKey.Marshal())
+	hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
+	return "SHA256:" + hash
+}

+ 18 - 0
ssh/keys_test.go

@@ -454,3 +454,21 @@ func TestKnownHostsParsing(t *testing.T) {
 		}
 	}
 }
+
+func TestFingerprintLegacyMD5(t *testing.T) {
+	pub, _ := getTestKey()
+	fingerprint := FingerprintLegacyMD5(pub)
+	want := "fb:61:6d:1a:e3:f0:95:45:3c:a0:79:be:4a:93:63:66" // ssh-keygen -lf -E md5 rsa
+	if fingerprint != want {
+		t.Errorf("got fingerprint %q want %q", fingerprint, want)
+	}
+}
+
+func TestFingerprintSHA256(t *testing.T) {
+	pub, _ := getTestKey()
+	fingerprint := FingerprintSHA256(pub)
+	want := "SHA256:Anr3LjZK8YVpjrxu79myrW9Hrb/wpcMNpVvTq/RcBm8" // ssh-keygen -lf rsa
+	if fingerprint != want {
+		t.Errorf("got fingerprint %q want %q", fingerprint, want)
+	}
+}