mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-26 11:37:33 +00:00
Use OpenSSL for Math_BigInteger::modPow speedups
Also, make Crypt_RSA's public keys compatible with OpenSSL and make it so __toString will return the key even when it's the public key that's loaded and it hasn't been set as the public key.
This commit is contained in:
parent
6c4fcd34d3
commit
2f8d1055ea
@ -849,8 +849,16 @@ class Crypt_RSA {
|
||||
$components['modulus'], $components['publicExponent']
|
||||
);
|
||||
|
||||
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPublicKey = chr(0) . $RSAPublicKey;
|
||||
$RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
|
||||
|
||||
$encapsulated = pack('Ca*a*',
|
||||
CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
chunk_split(base64_encode($RSAPublicKey)) .
|
||||
chunk_split(base64_encode($encapsulated)) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
@ -1465,6 +1473,30 @@ class Crypt_RSA {
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a minimalistic private key
|
||||
*
|
||||
* Returns the private key without the prime number constituants. Structurally identical to a public key that
|
||||
* hasn't been set as the public key
|
||||
*
|
||||
* @see getPrivateKey()
|
||||
* @access private
|
||||
* @param String $key
|
||||
* @param Integer $type optional
|
||||
*/
|
||||
function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
|
||||
{
|
||||
if (empty($this->modulus) || empty($this->exponent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldFormat = $this->publicKeyFormat;
|
||||
$this->publicKeyFormat = $mode;
|
||||
$temp = $this->_convertPublicKey($this->modulus, $this->exponent);
|
||||
$this->publicKeyFormat = $oldFormat;
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* __toString() magic method
|
||||
*
|
||||
@ -1476,7 +1508,7 @@ class Crypt_RSA {
|
||||
if ($key !== false) {
|
||||
return $key;
|
||||
}
|
||||
$key = $this->getPublicKey($this->publicKeyFormat);
|
||||
$key = $this->_getPrivatePublicKey($this->publicKeyFormat);
|
||||
return $key !== false ? $key : '';
|
||||
}
|
||||
|
||||
@ -2104,7 +2136,7 @@ class Crypt_RSA {
|
||||
* The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
|
||||
* private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
|
||||
* public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed
|
||||
* to be 2 regardless of which key is used. for compatability purposes, we'll just check to make sure the
|
||||
* to be 2 regardless of which key is used. For compatability purposes, we'll just check to make sure the
|
||||
* second byte is 2 or less. If it is, we'll accept the decrypted string as valid.
|
||||
*
|
||||
* As a consequence of this, a private key encrypted ciphertext produced with Crypt_RSA may not decrypt
|
||||
|
@ -70,7 +70,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVI Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version $Id: BigInteger.php 326530 2012-07-07 22:05:25Z terrafrost $
|
||||
* @version $Id: BigInteger.php,v 1.33 2010/03/22 22:32:03 terrafrost Exp $
|
||||
* @link http://pear.php.net/package/Math_BigInteger
|
||||
*/
|
||||
|
||||
@ -282,6 +282,10 @@ class Math_BigInteger {
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('openssl_public_encrypt') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE')) {
|
||||
define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
|
||||
}
|
||||
|
||||
switch ( MATH_BIGINTEGER_MODE ) {
|
||||
case MATH_BIGINTEGER_MODE_GMP:
|
||||
if (is_resource($x) && get_resource_type($x) == 'GMP integer') {
|
||||
@ -1591,6 +1595,53 @@ class Math_BigInteger {
|
||||
return $this->_normalize($temp->modPow($e, $n));
|
||||
}
|
||||
|
||||
if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP) {
|
||||
$temp = new Math_BigInteger();
|
||||
$temp->value = gmp_powm($this->value, $e->value, $n->value);
|
||||
|
||||
return $this->_normalize($temp);
|
||||
}
|
||||
|
||||
if ($this->compare(new Math_BigInteger()) < 0 || $this->compare($n) > 0) {
|
||||
list(, $temp) = $this->divide($n);
|
||||
return $temp->modPow($e, $n);
|
||||
}
|
||||
|
||||
if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
|
||||
$components = array(
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
|
||||
'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack('Ca*a*a*',
|
||||
48, $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'], $components['publicExponent']
|
||||
);
|
||||
|
||||
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPublicKey = chr(0) . $RSAPublicKey;
|
||||
$RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
|
||||
|
||||
$encapsulated = pack('Ca*a*',
|
||||
CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
chunk_split(base64_encode($encapsulated)) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
$plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
|
||||
|
||||
if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
|
||||
return new Math_BigInteger($result, 256);
|
||||
}
|
||||
}
|
||||
|
||||
switch ( MATH_BIGINTEGER_MODE ) {
|
||||
case MATH_BIGINTEGER_MODE_GMP:
|
||||
$temp = new Math_BigInteger();
|
||||
@ -3550,4 +3601,24 @@ class Math_BigInteger {
|
||||
$temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
|
||||
return $temp['int'];
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-encode an integer
|
||||
*
|
||||
* The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
|
||||
*
|
||||
* @see modPow()
|
||||
* @access private
|
||||
* @param Integer $length
|
||||
* @return String
|
||||
*/
|
||||
function _encodeASN1Length($length)
|
||||
{
|
||||
if ($length <= 0x7F) {
|
||||
return chr($length);
|
||||
}
|
||||
|
||||
$temp = ltrim(pack('N', $length), chr(0));
|
||||
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user