static function wrapPrivateKey($key, $algorithm, $attr, $password)
{
$asn1 = new ASN1();
$asn1->loadOIDs(oids);
$key = ['version' => 'v1', 'privateKeyAlgorithm' => ['algorithm' => $algorithm], 'privateKey' => Base64::encode($key)];
if (!empty($attr)) {
$key['attributes'] = $attr;
}
$key = $asn1->encodeDER($key, PrivateKeyInfo);
if (!empty($password) && is_string($password)) {
$salt = Random::string(8);
$iterationCount = self::$defaultIterationCount;
if (self::$defaultEncryptionAlgorithm == 'id-PBES2') {
$crypto = self::getPBES2EncryptionObject(self::$defaultEncryptionScheme);
$hash = str_replace('-', '/', substr(self::$defaultPRF, 11));
$kdf = 'pbkdf2';
$iv = Random::string($crypto->getBlockLength() >> 3);
$PBKDF2params = ['salt' => Base64::encode($salt), 'iterationCount' => $iterationCount, 'prf' => ['algorithm' => self::$defaultPRF, 'parameters' => null]];
$PBKDF2params = $asn1->encodeDER($PBKDF2params, PBKDF2params);
if (!$crypto instanceof RC2) {
$params = ['octetString' => Base64::encode($iv)];
} else {
$params = ['rc2ParametersVersion' => 58, 'iv' => Base64::encode($iv)];
$params = $asn1->encodeDER($params, RC2CBCParameter);
$params = new ASN1\Element($params);
}
$params = ['keyDerivationFunc' => ['algorithm' => 'id-PBKDF2', 'parameters' => new ASN1\Element($PBKDF2params)], 'encryptionScheme' => ['algorithm' => self::$defaultEncryptionScheme, 'parameters' => $params]];
$params = $asn1->encodeDER($params, PBES2params);
$crypto->setIV($iv);
} else {
$crypto = self::getPBES1EncryptionObject(self::$defaultEncryptionAlgorithm);
$hash = self::getPBES1Hash(self::$defaultEncryptionAlgorithm);
$kdf = self::getPBES1KDF(self::$defaultEncryptionAlgorithm);
$params = ['salt' => Base64::encode($salt), 'iterationCount' => $iterationCount];
$params = $asn1->encodeDER($params, PBEParameter);
}
$crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount);
$key = $crypto->encrypt($key);
$key = ['encryptionAlgorithm' => ['algorithm' => self::$defaultEncryptionAlgorithm, 'parameters' => new ASN1\Element($params)], 'encryptedData' => Base64::encode($key)];
$key = $asn1->encodeDER($key, EncryptedPrivateKeyInfo);
return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . chunk_split(Base64::encode($key), 64) . "-----END ENCRYPTED PRIVATE KEY-----";
}
return "-----BEGIN PRIVATE KEY-----\r\n" . chunk_split(Base64::encode($key), 64) . "-----END PRIVATE KEY-----";
}