From a67f4df16488f7eab64c596dc7aae24a2814dac9 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 4 May 2015 09:21:37 +0200 Subject: [PATCH 1/3] RSA: Add support for calculating a public key's fingerprint --- phpseclib/Crypt/RSA.php | 36 ++++++++++++++++++++++++++++ tests/Unit/Crypt/RSA/LoadKeyTest.php | 16 +++++++++++++ 2 files changed, 52 insertions(+) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 1910550b..09778caf 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1705,6 +1705,42 @@ class RSA return $temp; } + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @access public + * @param String $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + */ + public function getPublicKeyFingerprint($algorithm = 'md5') + { + if (empty($this->modulus) || empty($this->publicExponent)) { + return false; + } + + $modulus = $this->modulus->toBytes(true); + $publicExponent = $this->publicExponent->toBytes(true); + + $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); + + switch($algorithm) + { + case 'sha256': + $hash = new Hash; + $base = base64_encode($hash->_sha256($RSAPublicKey)); + return substr($base, 0, strlen($base)-1); + case 'md5': + return join(':', str_split(md5($RSAPublicKey), 2)); + default: + return false; + } + + } + /** * Returns the private key * diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index f7462777..a80b8d2f 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -241,6 +241,22 @@ ZQIDAQAB $this->assertFalse($rsa->getPrivateKey()); } + public function testSSHPubKeyFingerprint() + { + $rsa = new RSA(); + + $key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD9K+ebJRMN10kGanhi6kDz6EYFqZttZWZh0'. + 'YoEbIbbere9N2Yvfc7oIoCTHYowhXND9WSJaIs1E4bx0085CZnofWaqf4NbZTzAh18iZup08ec'. + 'COB5gJVS1efpgVSviDF2L7jxMsBVoOBfqsmA8m0RwDDVezyWvw4y+STSuVzu2jI8EfwN7ZFGC6'. + 'Yo8m/Z94qIGzqPYGKJLuCeidB0TnUE0ZtzOJTiOc/WoTm/NOpCdfQZEJggd1MOTi+QUnqRu4Wu'. + 'b6wYtY/q/WtUFr3nK+x0lgOtokhnJfRR/6fnmC1CztPnIT4BWK81VGKWONAxuhMyQ5XChyu6S9'. + 'mWG5tUlUI/5'; + + $this->assertTrue($rsa->loadKey($key)); + $this->assertSame($rsa->getPublicKeyFingerprint('md5'), 'bd:2c:2f:31:b9:ef:b8:f8:ad:fc:40:a6:94:4f:28:82'); + $this->assertSame($rsa->getPublicKeyFingerprint('sha256'), 'N9sV2uSNZEe8TITODku0pRI27l+Zk0IY0TrRTw3ozwM'); + } + public function testSetPrivate() { $rsa = new RSA(); From c46890b00cd3c2258896af84ab6b1156e65d1fa1 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 5 May 2015 08:51:17 +0200 Subject: [PATCH 2/3] RSA fingerprint feature fix Proper Hash usage, PHP 4 compatibility --- phpseclib/Crypt/RSA.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 09778caf..1aa9f914 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1730,11 +1730,11 @@ class RSA switch($algorithm) { case 'sha256': - $hash = new Hash; - $base = base64_encode($hash->_sha256($RSAPublicKey)); + $hash = new Hash('sha256'); + $base = base64_encode($hash->hash($RSAPublicKey)); return substr($base, 0, strlen($base)-1); case 'md5': - return join(':', str_split(md5($RSAPublicKey), 2)); + return substr(chunk_split($RSAPublicKey, 2, ':'), 0, -1); default: return false; } From 10d88c9c17dc3ee5dae486e28c0e35a21708e37c Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 6 May 2015 08:27:15 +0200 Subject: [PATCH 3/3] RSA fingerprint: Fix missing md5 --- phpseclib/Crypt/RSA.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 1aa9f914..0ce2713c 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1734,7 +1734,7 @@ class RSA $base = base64_encode($hash->hash($RSAPublicKey)); return substr($base, 0, strlen($base)-1); case 'md5': - return substr(chunk_split($RSAPublicKey, 2, ':'), 0, -1); + return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1); default: return false; }