Skip to content
This repository has been archived by the owner on Dec 30, 2020. It is now read-only.

Commit

Permalink
PHPSecLib removed and Support for RSA key without all primes added (#115
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Spomky authored Jul 30, 2016
1 parent f708ed4 commit e3206a0
Show file tree
Hide file tree
Showing 24 changed files with 1,065 additions and 105 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ before_script:
- mkdir -p build/logs

script:
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml

after_success:
after_script:
- vendor/bin/coveralls --no-interaction
- php ./examples/Encrypt1.php
- php ./examples/Encrypt2.php
Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@
}
},
"require": {
"php": ">=5.6",
"php": "^5.6|^7.0",
"lib-openssl": "*",
"spomky-labs/base64url": "^1.0",
"spomky-labs/aes-key-wrap": "^2.0",
"spomky-labs/php-aes-gcm": "^1.0",
"phpseclib/phpseclib": "^2.0",
"beberlei/assert": "^2.0",
"symfony/polyfill-mbstring": "^1.1",
"symfony/polyfill-php70": "^1.1",
Expand Down
62 changes: 33 additions & 29 deletions src/Algorithm/KeyEncryption/RSA.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,43 @@
use Assert\Assertion;
use Jose\KeyConverter\RSAKey;
use Jose\Object\JWKInterface;
use phpseclib\Crypt\RSA as PHPSecLibRSA;
use Jose\Util\RSA as JoseRSA;

/**
* Class RSA.
*/
abstract class RSA implements KeyEncryptionInterface
{
/**
* Optimal Asymmetric Encryption Padding (OAEP).
*/
const ENCRYPTION_OAEP = 1;

/**
* Use PKCS#1 padding.
*/
const ENCRYPTION_PKCS1 = 2;

/**
* {@inheritdoc}
*/
public function encryptKey(JWKInterface $key, $cek, array $complete_headers, array &$additional_headers)
{
$this->checkKey($key);

$pem = RSAKey::toPublic(new RSAKey($key))->toPEM();
$rsa = $this->getRsaObject();
$rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);
$pub = RSAKey::toPublic(new RSAKey($key));

if (self::ENCRYPTION_OAEP === $this->getEncryptionMode()) {
$encrypted = JoseRSA::encrypt($pub, $cek, $this->getHashAlgorithm());
Assertion::string($encrypted, 'Unable to encrypt the data.');

$encrypted = $rsa->encrypt($cek);
Assertion::string($encrypted, 'Unable to encrypt the data.');
return $encrypted;
} else {
$res = openssl_public_encrypt($cek, $encrypted, $pub->toPEM(), OPENSSL_PKCS1_PADDING | OPENSSL_RAW_DATA);
Assertion::true($res, 'Unable to encrypt the data.');

return $encrypted;
return $encrypted;
}
}

/**
Expand All @@ -46,14 +61,19 @@ public function decryptKey(JWKInterface $key, $encrypted_key, array $header)
$this->checkKey($key);
Assertion::true($key->has('d'), 'The key is not a private key');

$pem = (new RSAKey($key))->toPEM();
$rsa = $this->getRsaObject();
$rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);
$priv = new RSAKey($key);

if (self::ENCRYPTION_OAEP === $this->getEncryptionMode()) {
$decrypted = JoseRSA::decrypt($priv, $encrypted_key, $this->getHashAlgorithm());
Assertion::string($decrypted, 'Unable to decrypt the data.');

$decrypted = $rsa->decrypt($encrypted_key);
Assertion::string($decrypted, 'Unable to decrypt the data.');
return $decrypted;
} else {
$res = openssl_private_decrypt($encrypted_key, $decrypted, $priv->toPEM(), OPENSSL_PKCS1_PADDING | OPENSSL_RAW_DATA);
Assertion::true($res, 'Unable to decrypt the data.');

return $decrypted;
return $decrypted;
}
}

/**
Expand All @@ -64,22 +84,6 @@ public function getKeyManagementMode()
return self::MODE_ENCRYPT;
}

/**
* @return \phpseclib\Crypt\RSA
*/
private function getRsaObject()
{
$rsa = new PHPSecLibRSA();
$encryption_mode = $this->getEncryptionMode();
$rsa->setEncryptionMode($encryption_mode);
if (PHPSecLibRSA::ENCRYPTION_OAEP === $encryption_mode) {
$rsa->setHash($this->getHashAlgorithm());
$rsa->setMGFHash($this->getHashAlgorithm());
}

return $rsa;
}

/**
* @param JWKInterface $key
*/
Expand Down
4 changes: 1 addition & 3 deletions src/Algorithm/KeyEncryption/RSA15.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

namespace Jose\Algorithm\KeyEncryption;

use phpseclib\Crypt\RSA as PHPSecLibRSA;

/**
* Class RSA15.
*/
Expand All @@ -23,7 +21,7 @@ final class RSA15 extends RSA
*/
protected function getEncryptionMode()
{
return PHPSecLibRSA::ENCRYPTION_PKCS1;
return self::ENCRYPTION_PKCS1;
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/Algorithm/KeyEncryption/RSAOAEP.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

namespace Jose\Algorithm\KeyEncryption;

use phpseclib\Crypt\RSA as PHPSecLibRSA;

/**
* Class RSAOAEP.
*/
Expand All @@ -23,7 +21,7 @@ final class RSAOAEP extends RSA
*/
protected function getEncryptionMode()
{
return PHPSecLibRSA::ENCRYPTION_OAEP;
return self::ENCRYPTION_OAEP;
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/Algorithm/KeyEncryption/RSAOAEP256.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

namespace Jose\Algorithm\KeyEncryption;

use phpseclib\Crypt\RSA as PHPSecLibRSA;

/**
* Class RSAOAEP256.
*/
Expand All @@ -23,7 +21,7 @@ final class RSAOAEP256 extends RSA
*/
public function getEncryptionMode()
{
return PHPSecLibRSA::ENCRYPTION_OAEP;
return self::ENCRYPTION_OAEP;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Algorithm/Signature/ECDSA.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function verify(JWKInterface $key, $data, $signature)
* @param string $R
* @param string $S
*
* @return boolean
* @return bool
*/
private function verifyOpenSSLSignature(JWKInterface $key, $data, $R, $S)
{
Expand All @@ -144,7 +144,7 @@ private function verifyOpenSSLSignature(JWKInterface $key, $data, $R, $S)
* @param string $R
* @param string $S
*
* @return boolean
* @return bool
*/
private function verifyPHPECCSignature(JWKInterface $key, $data, $R, $S)
{
Expand Down
37 changes: 10 additions & 27 deletions src/Algorithm/Signature/RSA.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@
use Jose\Algorithm\SignatureAlgorithmInterface;
use Jose\KeyConverter\RSAKey;
use Jose\Object\JWKInterface;
use phpseclib\Crypt\RSA as PHPSecLibRSA;
use Jose\Util\RSA as JoseRSA;

/**
* Class RSA.
*/
abstract class RSA implements SignatureAlgorithmInterface
{
/**
* Probabilistic Signature Scheme
* Probabilistic Signature Scheme.
*/
const SIGNATURE_PSS = 1;

/**
* Use the PKCS#1
* Use the PKCS#1.
*/
const SIGNATURE_PKCS1 = 2;

Expand All @@ -49,15 +49,14 @@ public function verify(JWKInterface $key, $input, $signature)
{
$this->checkKey($key);

$pem = RSAKey::toPublic(new RSAKey($key))->toPEM();
$pub = RSAKey::toPublic(new RSAKey($key));

if ($this->getSignatureMethod() === self::SIGNATURE_PSS) {
$rsa = $this->getRsaObject();
$rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);

return $rsa->verify($input, $signature);
return JoseRSA::verify($pub, $input, $signature, $this->getAlgorithm());
} else {
return 1 === openssl_verify($input, $signature, $pem, $this->getAlgorithm());

return 1 === openssl_verify($input, $signature, $pub->toPEM(), $this->getAlgorithm());
}
}

Expand All @@ -69,17 +68,15 @@ public function sign(JWKInterface $key, $input)
$this->checkKey($key);
Assertion::true($key->has('d'), 'The key is not a private key');

$pem = (new RSAKey($key))->toPEM();
$priv = new RSAKey($key);

if ($this->getSignatureMethod() === self::SIGNATURE_PSS) {
$rsa = $this->getRsaObject();
$rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);
$result = $rsa->sign($input);
$result = JoseRSA::sign($priv, $input, $this->getAlgorithm());
Assertion::string($result, 'An error occurred during the creation of the signature');

return $result;
} else {
$result = openssl_sign($input, $signature, $pem, $this->getAlgorithm());
$result = openssl_sign($input, $signature, $priv->toPEM(), $this->getAlgorithm());
Assertion::true($result, 'Unable to sign');

return $signature;
Expand All @@ -93,18 +90,4 @@ private function checkKey(JWKInterface $key)
{
Assertion::eq($key->get('kty'), 'RSA', 'Wrong key type.');
}

/**
* @return \phpseclib\Crypt\RSA
*/
private function getRsaObject()
{
$rsa = new PHPSecLibRSA();
$rsa->setHash($this->getAlgorithm());
$rsa->setMGFHash($this->getAlgorithm());
$rsa->setSaltLength(0);
$rsa->setSignatureMode(PHPSecLibRSA::SIGNATURE_PSS);

return $rsa;
}
}
2 changes: 1 addition & 1 deletion src/Behaviour/EncrypterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ private function areKeyManagementModesCompatible($current, $new)
$dir = Algorithm\KeyEncryptionAlgorithmInterface::MODE_DIRECT;
$enc = Algorithm\KeyEncryptionAlgorithmInterface::MODE_ENCRYPT;
$wrap = Algorithm\KeyEncryptionAlgorithmInterface::MODE_WRAP;
$supported_key_management_mode_combinations = [$enc.$enc => true,$enc.$wrap => true,$wrap.$enc => true,$wrap.$wrap => true,$agree.$agree => false,$agree.$dir => false,$agree.$enc => false,$agree.$wrap => false,$dir.$agree => false,$dir.$dir => false,$dir.$enc => false,$dir.$wrap => false,$enc.$agree => false,$enc.$dir => false,$wrap.$agree => false,$wrap.$dir => false,];
$supported_key_management_mode_combinations = [$enc.$enc => true, $enc.$wrap => true, $wrap.$enc => true, $wrap.$wrap => true, $agree.$agree => false, $agree.$dir => false, $agree.$enc => false, $agree.$wrap => false, $dir.$agree => false, $dir.$dir => false, $dir.$enc => false, $dir.$wrap => false, $enc.$agree => false, $enc.$dir => false, $wrap.$agree => false, $wrap.$dir => false];

if (array_key_exists($current.$new, $supported_key_management_mode_combinations)) {
return $supported_key_management_mode_combinations[$current.$new];
Expand Down
3 changes: 2 additions & 1 deletion src/Decrypter.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public static function createDecrypter(array $key_encryption_algorithms, array $
* @param string[]|\Jose\Algorithm\ContentEncryptionAlgorithmInterface[] $content_encryption_algorithms
* @param string[]|\Jose\Compression\CompressionInterface[] $compression_methods
*/
public function __construct(array $key_encryption_algorithms, array $content_encryption_algorithms, array $compression_methods) {
public function __construct(array $key_encryption_algorithms, array $content_encryption_algorithms, array $compression_methods)
{
$this->setKeyEncryptionAlgorithms($key_encryption_algorithms);
$this->setContentEncryptionAlgorithms($content_encryption_algorithms);
$this->setCompressionMethods($compression_methods);
Expand Down
2 changes: 1 addition & 1 deletion src/Encrypter.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ private function getEncryptedKeyFromKeyAgreementAndKeyWrappingAlgorithm(array $c
*/
private function getEncryptedKeyFromKeyEncryptionAlgorithm(array $complete_headers, $cek, Algorithm\KeyEncryption\KeyEncryptionInterface $key_encryption_algorithm, Object\JWKInterface $recipient_key, array &$additional_headers)
{
return $key_encryption_algorithm->encryptKey($recipient_key, $cek, $complete_headers, $additional_headers);
return $key_encryption_algorithm->encryptKey($recipient_key, $cek, $complete_headers, $additional_headers);
}

/**
Expand Down
Loading

0 comments on commit e3206a0

Please sign in to comment.