Convert a public key to the appropriate format

@access private
@see self::setPublicKeyFormat()
@param string $RSAPrivateKey
@return string
510545
function _convertPublicKey($n, $e)
    {
        $signed = $this->publicKeyFormat != CRYPT_RSA_PUBLIC_FORMAT_XML;

        $modulus = $n->toBytes($signed);
        $publicExponent = $e->toBytes($signed);

        switch ($this->publicKeyFormat) {
            case CRYPT_RSA_PUBLIC_FORMAT_RAW:
                return array('e' => $e->copy(), 'n' => $n->copy());
            case CRYPT_RSA_PUBLIC_FORMAT_XML:
                return "<RSAKeyValue>\r\n" .
                       '  <Modulus>' . base64_encode($modulus) . "</Modulus>\r\n" .
                       '  <Exponent>' . base64_encode($publicExponent) . "</Exponent>\r\n" .
                       '</RSAKeyValue>';
                break;
            case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
                // from <http://tools.ietf.org/html/rfc4253#page-15>:
                // string    "ssh-rsa"
                // mpint     e
                // mpint     n
                $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
                $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;

                return $RSAPublicKey;
            default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW or CRYPT_RSA_PUBLIC_FORMAT_PKCS1
                // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
                // RSAPublicKey ::= SEQUENCE {
                //     modulus           INTEGER,  -- n
                //     publicExponent    INTEGER   -- e
                // }
                $components = array(
                    'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
                    'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
                );

                $RSAPublicKey = pack(
                    'Ca*a*a*',
                    CRYPT_RSA_ASN1_SEQUENCE,
                    $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
                    $components['modulus'],
                    $components['publicExponent']
                );

                if ($this->publicKeyFormat == CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) {
                    $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
                                    chunk_split(base64_encode($RSAPublicKey), 64) .
                                    '-----END RSA PUBLIC KEY-----';
                } else {
                    // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
                    $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
                    $RSAPublicKey = chr(0) . $RSAPublicKey;
                    $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;

                    $RSAPublicKey = 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), 64) .
                                     '-----END PUBLIC KEY-----';
                }

                return $RSAPublicKey;
        }
    }
268963
public static function generateSign($parmas, $privateKey = null): string
    {
        if (is_null($privateKey)) {
            throw new InvalidConfigException('Missing Alipay Config -- [private_key]');
        }

        if (Str::endsWith($privateKey, '.pem')) {
            $privateKey = openssl_pkey_get_private($privateKey);
        } else {
            $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n".
                wordwrap($privateKey, 64, "\n", true).
                "\n-----END RSA PRIVATE KEY-----";
        }

        openssl_sign(self::getSignContent($parmas), $sign, $privateKey, OPENSSL_ALGO_SHA256);

        return base64_encode($sign);
    }
424282
public function addPublicKey($publicKey, $privateKey) {
        $this->validatePublicKeyName($publicKey);

        if ($this->publicKeyExists($publicKey)) {
            throw new InvalidArgumentException(
                'Public key with name "' . $publicKey . '" already exists'
            );
        }

        return $this->getCommand('EditPublicKey', array(
            'properties' => json_encode(array('privateKey' => $privateKey)),
            'publicKey' => $publicKey,
        ))->execute();
    }
1267278
public static function getSigningPublicKeyFromResponse(string $response) : string
    {
        $version = static::getVersion($response);
        if ($version === 2) {
            if (\strlen($response) < 236) {
                throw new InvalidArgumentException;
            }

            return \substr($response, -160, 32);
        }

        throw new InvalidArgumentException('The response provided is not suitable for public key extraction.');
    }
1133767
public static String RSAKeyToString (PrivateKey key)
    {
        try {
            KeyFactory kf = KeyFactory.getInstance("RSA");
            RSAPrivateKeySpec spec = kf.getKeySpec(key, RSAPrivateKeySpec.class);
            StringBuilder buf = new StringBuilder();
            buf.append(spec.getModulus().toString(16))
                .append(SPLIT)
                .append(spec.getPrivateExponent().toString(16));
            return buf.toString();
        } catch (GeneralSecurityException gse) {
            log.warning("Failed to convert key to string", gse);
        }
        return null;
    }
314667
public function publicKeyToDer($publicKey)
    {
        try {
            return CryptoVirgilKeyPair::publicKeyToDER($publicKey);
        } catch (Exception $exception) {
            throw new PublicKeyToDerConvertingException($exception->getMessage(), $exception->getCode());
        }
    }
737907
public static function seal(
        string $plaintext,
        SealingPublicKey $publicKey
    ): string {
        $ephemeralSecret = SealingSecretKey::generate();
        $sharedSecret = static::keyExchange(
            $ephemeralSecret,
            $publicKey,
            false,
            56
        );
        $ephemeralPublicKey = $ephemeralSecret->getPublickey()->getString(true);
        $sharedKey = \ParagonIE_Sodium_Core_Util::substr($sharedSecret, 0, 32);
        $nonce = \ParagonIE_Sodium_Core_Util::substr($sharedSecret, 32, 24);
        try {
            \ParagonIE_Sodium_Compat::memzero($sharedSecret);
        } catch (\Throwable $ex) {
        }

        return $ephemeralPublicKey. \ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt(
            $plaintext,
            $ephemeralPublicKey,
            $nonce,
            $sharedKey
        );
    }
378989
private function formatApcCacheKey($key)
    {
        $pattern = $this->getApcCacheKeyPattern();
        if (preg_match($pattern, $key, $matches)) {
            $sns = $matches['stashNS'];
            $iid = trim($matches['itemID'], ':');
            $iid = preg_replace([ '/:+/', '/\.+/' ], [ '⇒', '/' ], $iid);
            $key = $matches['stashNS'].'⇒'.$iid;
        }

        return $key;
    }
1255056
public function encryptByPrivateKey_data($data, $privatekey = '')
	{
		$RSACrypt = new RSACrypt();

		if ($privatekey != "") {
			$RSACrypt->privkey = $privatekey;
		}
		$crypt_res = "";
		for ($i = 0; $i < ((strlen($data) - strlen($data) % 117) / 117 + 1); $i++) {
			$crypt_res = $crypt_res . ($RSACrypt->encryptByPrivateKey(mb_strcut($data, $i * 117, 117, 'utf-8')));
		}
		return $crypt_res;
	}
162326
public static function getPKCS1($key)
	{
		$prefix = '-----BEGIN RSA PUBLIC KEY-----';
		$postfix = '-----END RSA PUBLIC KEY-----';
		
		$key = str_replace($prefix, '', $key);
		$key = str_replace($postfix, '', $key);
		$key = str_replace("\n", '', $key);
		
		$lines = str_split($key, 65);
		$body = implode("\n", $lines);
		$result = $prefix . "\n";
		$result .= $body . "\n";
		$result .= $postfix;
		
		return $result;
	}
160233
public static function decrypt(RSAKey $key, $ciphertext, $hash_algorithm)
    {
        Assertion::greaterThan($key->getModulusLength(), 0);
        $hash = Hash::$hash_algorithm();
        $ciphertext = str_split($ciphertext, $key->getModulusLength());
        $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $key->getModulusLength(), chr(0), STR_PAD_LEFT);
        $plaintext = '';
        foreach ($ciphertext as $c) {
            $temp = self::getRSAESOAEP($key, $c, $hash);
            $plaintext .= $temp;
        }

        return $plaintext;
    }
27433
public function exportPublicKey(VirgilPublicKey $publicKey)
    {
        try {
            return $this->cryptoService->publicKeyToDer($publicKey->getValue());
        } catch (Exception $exception) {
            throw new VirgilCryptoException($exception->getMessage());
        }
    }
819962
public function setSharedKey($key)
    {
        // If the public key is a file name then convert it to
        // the contents of the file (which should be an RSA public
        // key in PEM format)
        if (file_exists($key)) {
            $this->shared_key = file_get_contents($key);
        } elseif (! empty($key)) {
            $this->shared_key = $key;
        }

        return $this;
    }
1285832
function _prepareKey($key)
    {
        static $shifts = array( // number of key bits shifted per round
            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
        );

        // pad the key and remove extra characters as appropriate.
        $key = str_pad(substr($key, 0, 8), 8, chr(0));

        $temp = unpack('Na/Nb', $key);
        $key = array($temp['a'], $temp['b']);
        $msb = array(
            ($key[0] >> 31) & 1,
            ($key[1] >> 31) & 1
        );
        $key[0] &= 0x7FFFFFFF;
        $key[1] &= 0x7FFFFFFF;

        $key = array(
            (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
            (($key[1] & 0x00020408) <<  8) | (($key[1] & 0x02040800) >>  1) |
            (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
            (($key[0] & 0x00020408) <<  4) | (($key[0] & 0x02040800) >>  5) |
            (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
            (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
            (($key[0] & 0x00000010) >>  1) | (($key[0] & 0x00001000) >> 10) |
            (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
        ,
            (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
            (($key[1] & 0x00800000) <<  2) | (($key[0] & 0x00000080) << 16) |
            (($key[0] & 0x00008000) <<  7) | (($key[0] & 0x00800000) >>  2) |
            (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) <<  4) |
            (($key[1] & 0x00400000) >>  5) | (($key[1] & 0x40000000) >> 14) |
            (($key[0] & 0x00000040) <<  9) | ( $key[0] & 0x00004000       ) |
            (($key[0] & 0x00400000) >>  9) | (($key[0] & 0x40000000) >> 18) |
            (($key[1] & 0x00000020) <<  6) | (($key[1] & 0x00002000) >>  3) |
            (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
            (($key[0] & 0x00000020) <<  2) | (($key[0] & 0x00002000) >>  7) |
            (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
            (($key[1] & 0x00000010) >>  1) | (($key[1] & 0x00001000) >> 10) |
            (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
            ($msb[1] << 24) | ($msb[0] << 20)
        ); 

        $keys = array();
        for ($i = 0; $i < 16; $i++) {
            $key[0] <<= $shifts[$i];
            $temp = ($key[0] & 0xF0000000) >> 28;
            $key[0] = ($key[0] | $temp) & 0x0FFFFFFF;

            $key[1] <<= $shifts[$i];
            $temp = ($key[1] & 0xF0000000) >> 28;
            $key[1] = ($key[1] | $temp) & 0x0FFFFFFF;

            $temp = array(
                (($key[1] & 0x00004000) >>  9) | (($key[1] & 0x00000800) >>  7) |
                (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >>  2) |
                (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
            ,
                (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) <<  4) |
                (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
                (($key[1] & 0x00000080) >>  6)
            ,
                ( $key[1] & 0x00000020       ) | (($key[1] & 0x00000200) >>  5) |
                (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
                (($key[1] & 0x00000004) >>  1) | (($key[1] & 0x00100000) >> 20)
            ,
                (($key[1] & 0x00001000) >>  7) | (($key[1] & 0x00200000) >> 17) |
                (($key[1] & 0x00000002) <<  2) | (($key[1] & 0x00000100) >>  6) |
                (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
            ,
                (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010       ) |
                (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
                (($key[0] & 0x00000200) >>  8) | (($key[0] & 0x00000002) >>  1)
            ,
                (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
                (($key[0] & 0x00000020) >>  2) | (($key[0] & 0x00000800) >>  9) |
                (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >>  8)
            ,
                (($key[0] & 0x00001000) >>  7) | (($key[0] & 0x00000088) >>  3) |
                (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) <<  2) |
                (($key[0] & 0x00400000) >> 21)
            ,
                (($key[0] & 0x00000400) >>  5) | (($key[0] & 0x00004000) >> 10) |
                (($key[0] & 0x00000040) >>  3) | (($key[0] & 0x00100000) >> 18) |
                (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
            );

            $keys[] = $temp;
        }

        $temp = array(
            CRYPT_DES_ENCRYPT => $keys,
            CRYPT_DES_DECRYPT => array_reverse($keys)
        );

        return $temp;
    }
287784
public function setKey($key = null)
    {
        if (empty($key)) {

            $key = $this->get('private_key');

            if (empty($key)) {
                $key = gplcart_string_random();
                $this->set('private_key', $key);
            }

        } else {
            $this->set('private_key', $key);
        }

        return $this->key = $key;
    }
958609
function _reformatKey($algorithm, $key)
    {
        switch ($algorithm) {
            case 'rsaEncryption':
                return
                    "-----BEGIN RSA PUBLIC KEY-----\r\n" .
                    // subjectPublicKey is stored as a bit string in X.509 certs.  the first byte of a bit string represents how many bits
                    // in the last byte should be ignored.  the following only supports non-zero stuff but as none of the X.509 certs Firefox
                    // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do.
                    chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) .
                    '-----END RSA PUBLIC KEY-----';
            default:
                return $key;
        }
    }
1353101
public function getPrivateKey()
    {
        if ("---" !== substr($this->privateKey, 0, 3) && is_file($this->privateKey)) {
            $this->privateKey = file_get_contents($this->privateKey);
        }

        $key = new RSA();

        if ($password = $this->getPassword()) {
            $key->setPassword($password);
        }

        $key->loadKey($this->privateKey);

        return $key;
    }