mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-26 11:37:33 +00:00
RSA: make it so you can't sign w/ public key, decrypt w/ private
This commit is contained in:
parent
63b6df29a8
commit
55384afdac
@ -52,6 +52,8 @@ use phpseclib\Common\Functions\Strings;
|
||||
use phpseclib\File\ASN1\Maps\DigestInfo;
|
||||
use phpseclib\Crypt\Common\AsymmetricKey;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
use phpseclib\Exception\UnsupportedOperationException;
|
||||
use phpseclib\Exception\NoKeyLoadedException;
|
||||
|
||||
/**
|
||||
* Pure-PHP PKCS#1 compliant implementation of RSA.
|
||||
@ -201,7 +203,6 @@ class RSA extends AsymmetricKey
|
||||
*/
|
||||
private $sLen;
|
||||
|
||||
|
||||
/**
|
||||
* Comment
|
||||
*
|
||||
@ -243,6 +244,14 @@ class RSA extends AsymmetricKey
|
||||
*/
|
||||
private static $defaultExponent = 65537;
|
||||
|
||||
/**
|
||||
* Is the loaded key a public key?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
private $isPublic = false;
|
||||
|
||||
/**
|
||||
* Smallest Prime
|
||||
*
|
||||
@ -450,6 +459,7 @@ class RSA extends AsymmetricKey
|
||||
$publickey->k = $bits >> 3;
|
||||
$publickey->exponent = $e;
|
||||
$publickey->publicExponent = $e;
|
||||
$publickey->isPublic = true;
|
||||
|
||||
return compact('privatekey', 'publickey');
|
||||
}
|
||||
@ -475,6 +485,7 @@ class RSA extends AsymmetricKey
|
||||
$this->sLen = $key->sLen;
|
||||
$this->mgfHLen = $key->mgfHLen;
|
||||
$this->password = $key->password;
|
||||
$this->isPublic = $key->isPublic;
|
||||
|
||||
if (is_object($key->hash)) {
|
||||
$this->hash = new Hash($key->hash->getHash());
|
||||
@ -524,6 +535,7 @@ class RSA extends AsymmetricKey
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->isPublic = false;
|
||||
$this->modulus = $components['modulus'];
|
||||
$this->k = $this->modulus->getLengthInBytes();
|
||||
$this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
|
||||
@ -669,6 +681,7 @@ class RSA extends AsymmetricKey
|
||||
}
|
||||
|
||||
if ($key === false && !empty($this->modulus)) {
|
||||
$this->isPublic = true;
|
||||
$this->publicExponent = $this->exponent;
|
||||
return true;
|
||||
}
|
||||
@ -681,6 +694,7 @@ class RSA extends AsymmetricKey
|
||||
if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
|
||||
$this->modulus = $components['modulus'];
|
||||
$this->exponent = $this->publicExponent = $components['publicExponent'];
|
||||
$this->isPublic = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -689,6 +703,18 @@ class RSA extends AsymmetricKey
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the key self-identify as being a public key or not?
|
||||
*
|
||||
* @see self::isPublicKey()
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublicKey()
|
||||
{
|
||||
return $this->isPublic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the private key
|
||||
*
|
||||
@ -1729,6 +1755,14 @@ class RSA extends AsymmetricKey
|
||||
*/
|
||||
public function encrypt($plaintext, $padding = self::PADDING_OAEP)
|
||||
{
|
||||
if (empty($this->modulus) || empty($this->exponent)) {
|
||||
throw new NoKeyLoadedException('No key has been loaded');
|
||||
}
|
||||
|
||||
if (!$this->isPublic) {
|
||||
throw new UnsupportedOperationException('phpseclib does not allow the use of private keys to encrypt data');
|
||||
}
|
||||
|
||||
switch ($padding) {
|
||||
case self::PADDING_NONE:
|
||||
return $this->raw_encrypt($plaintext);
|
||||
@ -1752,6 +1786,14 @@ class RSA extends AsymmetricKey
|
||||
*/
|
||||
public function decrypt($ciphertext, $padding = self::PADDING_OAEP)
|
||||
{
|
||||
if (empty($this->modulus) || empty($this->exponent)) {
|
||||
throw new NoKeyLoadedException('No key has been loaded');
|
||||
}
|
||||
|
||||
if ($this->isPublic) {
|
||||
throw new UnsupportedOperationException('phpseclib does not allow the use of public keys to decrypt data');
|
||||
}
|
||||
|
||||
switch ($padding) {
|
||||
case self::PADDING_NONE:
|
||||
return $this->raw_encrypt($ciphertext);
|
||||
@ -1775,7 +1817,11 @@ class RSA extends AsymmetricKey
|
||||
public function sign($message, $padding = self::PADDING_PSS)
|
||||
{
|
||||
if (empty($this->modulus) || empty($this->exponent)) {
|
||||
return false;
|
||||
throw new NoKeyLoadedException('No key has been loaded');
|
||||
}
|
||||
|
||||
if ($this->isPublic) {
|
||||
throw new UnsupportedOperationException('phpseclib does not allow the use of public keys to sign data');
|
||||
}
|
||||
|
||||
switch ($padding) {
|
||||
@ -1801,7 +1847,11 @@ class RSA extends AsymmetricKey
|
||||
public function verify($message, $signature, $padding = self::PADDING_PSS)
|
||||
{
|
||||
if (empty($this->modulus) || empty($this->exponent)) {
|
||||
return false;
|
||||
throw new NoKeyLoadedException('No key has been loaded');
|
||||
}
|
||||
|
||||
if (!$this->isPublic) {
|
||||
throw new UnsupportedOperationException('phpseclib does not allow the use of private keys to verify data');
|
||||
}
|
||||
|
||||
switch ($padding) {
|
||||
|
26
phpseclib/Exception/NoKeyLoadedException.php
Normal file
26
phpseclib/Exception/NoKeyLoadedException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NoKeyLoadedException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package NoKeyLoadedException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* NoKeyLoadedException
|
||||
*
|
||||
* @package NoKeyLoadedException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class NoKeyLoadedException extends \RuntimeException
|
||||
{
|
||||
}
|
26
phpseclib/Exception/UnsupportedOperationException.php
Normal file
26
phpseclib/Exception/UnsupportedOperationException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UnsupportedOperationException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package UnsupportedOperationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedOperationException
|
||||
*
|
||||
* @package UnsupportedOperationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class UnsupportedOperationException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -518,7 +518,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
|
||||
= "\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']));
|
||||
/* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier."
|
||||
-- https://tools.ietf.org/html/rfc3279#section-2.3.1
|
||||
|
||||
@ -1235,6 +1235,8 @@ class X509
|
||||
case 'rsaEncryption':
|
||||
$rsa = new RSA();
|
||||
$rsa->load($publicKey);
|
||||
//zzzzz
|
||||
$rsa->setPublicKey();
|
||||
|
||||
switch ($signatureAlgorithm) {
|
||||
case 'md2WithRSAEncryption':
|
||||
@ -2036,7 +2038,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
|
||||
= "\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']));
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null;
|
||||
$csr['signatureAlgorithm']['parameters'] = null;
|
||||
$csr['certificationRequestInfo']['signature']['parameters'] = null;
|
||||
@ -2122,7 +2124,6 @@ class X509
|
||||
case 'rsaEncryption':
|
||||
$this->publicKey = new RSA();
|
||||
$this->publicKey->load($key);
|
||||
$this->publicKey->setPublicKey();
|
||||
break;
|
||||
default:
|
||||
$this->publicKey = null;
|
||||
@ -2157,7 +2158,7 @@ class X509
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']
|
||||
= Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])));
|
||||
= "\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,4 +132,82 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
$rsa->load($rsa->getPublicKey());
|
||||
$this->assertTrue($rsa->verify($plaintext, $sig));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedOperationException
|
||||
*/
|
||||
public function testPrivateEncrypt()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$privatekey = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->load($privatekey);
|
||||
|
||||
$rsa->encrypt('hello, world!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedOperationException
|
||||
*/
|
||||
public function testPublicSign()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->load('-----BEGIN RSA PUBLIC KEY-----
|
||||
MIGJAoGBAMuqkz8ij+ESAaNvgocVGmapjlrIldmhRo4h2NX4e6IXiCLTSxASQtY4
|
||||
iqRnmyxqQSfaan2okTfQ6sP95bl8Qz8lgneW3ClC6RXG/wpJgsx7TXQ2kodlcKBF
|
||||
m4k72G75QXhZ+I40ZG7cjBf1/9egakR0a0X0MpeOrKCzMBLv9+mpAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----');
|
||||
|
||||
$rsa->sign('hello, world!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedOperationException
|
||||
*/
|
||||
public function testPublicDecrypt()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->load('-----BEGIN RSA PUBLIC KEY-----
|
||||
MIGJAoGBAMuqkz8ij+ESAaNvgocVGmapjlrIldmhRo4h2NX4e6IXiCLTSxASQtY4
|
||||
iqRnmyxqQSfaan2okTfQ6sP95bl8Qz8lgneW3ClC6RXG/wpJgsx7TXQ2kodlcKBF
|
||||
m4k72G75QXhZ+I40ZG7cjBf1/9egakR0a0X0MpeOrKCzMBLv9+mpAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----');
|
||||
|
||||
$rsa->decrypt('zzz');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \phpseclib\Exception\UnsupportedOperationException
|
||||
*/
|
||||
public function testPrivateVerify()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$privatekey = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->load($privatekey);
|
||||
|
||||
$rsa->verify('hello, world!', 'dummysignature');
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,7 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase
|
||||
|
||||
public function testSaveSPKAC()
|
||||
{
|
||||
$privKey = new RSA();
|
||||
extract($privKey->createKey());
|
||||
extract(RSA::createKey());
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->setPrivateKey($privatekey);
|
||||
@ -59,7 +58,7 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase
|
||||
$this->assertInternalType('string', $x509->saveSPKAC($spkac));
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->setPrivateKey($privKey);
|
||||
$x509->setPrivateKey($privatekey);
|
||||
|
||||
$spkac = $x509->signSPKAC();
|
||||
$this->assertInternalType('array', $spkac);
|
||||
|
Loading…
Reference in New Issue
Block a user