本文整理汇总了PHP中Crypt_AES::setKeyLength方法的典型用法代码示例。如果您正苦于以下问题:PHP Crypt_AES::setKeyLength方法的具体用法?PHP Crypt_AES::setKeyLength怎么用?PHP Crypt_AES::setKeyLength使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Crypt_AES
的用法示例。
在下文中一共展示了Crypt_AES::setKeyLength方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: initAes
protected function initAes($key, $iv, $keySize)
{
$this->aes = new \Crypt_AES();
$this->aes->setKeyLength($keySize);
$this->aesKey = $key;
$this->aesIV = $iv;
$this->aes->setKey($this->aesKey);
$this->aes->setIV($this->aesIV);
}
示例2: decrypt
public static function decrypt($secret, $password, ApiKeyEncryptionOptions $options)
{
$decodedSecret = self::base64url_decode($secret);
$salt = self::base64url_decode($options->getEncryptionKeySalt());
$iterations = $options->getEncryptionKeyIterations();
$keyLengthBits = $options->getEncryptionKeySize();
$iv = substr($decodedSecret, 0, 16);
$aes = new \Crypt_AES();
$aes->setPassword($password, 'pbkdf2', 'sha1', $salt, $iterations, $keyLengthBits / 8);
$aes->setKeyLength($keyLengthBits);
$aes->setIV($iv);
return $aes->decrypt(substr($decodedSecret, 16));
}
示例3: loginWSAuthenticate
/**
* Checks whether a user has the right to enter on the platform or not
* @param string The username, as provided in form
* @param string The cleartext password, as provided in form
* @param string The WS URL, as provided at the beginning of this script
*/
function loginWSAuthenticate($username, $password, $wsUrl)
{
// check params
if (empty($username) or empty($password) or empty($wsUrl)) {
return false;
}
// Create new SOAP client instance
$client = new SoapClient($wsUrl);
if (!$client) {
return false;
}
// Include phpseclib methods, because of a bug with AES/CFB in mcrypt
include_once api_get_path(LIBRARY_PATH) . 'phpseclib/Crypt/AES.php';
// Define all elements necessary to the encryption
$key = '-+*%$({[]})$%*+-';
// Complete password con PKCS7-specific padding
$blockSize = 16;
$padding = $blockSize - strlen($password) % $blockSize;
$password .= str_repeat(chr($padding), $padding);
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(128);
$cipher->setKey($key);
$cipher->setIV($key);
$cipheredPass = $cipher->encrypt($password);
// Mcrypt call left for documentation purposes - broken, see https://bugs.php.net/bug.php?id=51146
//$cipheredPass = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_CFB, $key);
// Following lines present for debug purposes only
/*
$arr = preg_split('//', $cipheredPass, -1, PREG_SPLIT_NO_EMPTY);
foreach ($arr as $char) {
error_log(ord($char));
}
*/
// Change to base64 to avoid communication alteration
$passCrypted = base64_encode($cipheredPass);
// The call to the webservice will change depending on your definition
try {
$response = $client->validateUser(array('user' => $username, 'pass' => $passCrypted, 'system' => 'chamilo'));
} catch (SoapFault $fault) {
error_log('Caught something');
if ($fault->faultstring != 'Could not connect to host') {
error_log('Not a connection problem');
throw $fault;
} else {
error_log('Could not connect to WS host');
}
return 0;
}
return $response->validateUserResult;
}
示例4: initSymmetric
/**
* Initializes AES instance using either provided $options or session values
* @param array $options Array of options, containing 'key' and 'iv' values
* @return mixed|void
* @throws Exception
*/
public function initSymmetric($options = array())
{
if (empty($options) && Session::has('aes_key') && Session::has('aes_iv')) {
$options = array('key' => Session::get('aes_key'), 'iv' => Session::get('aes_iv'));
}
if (!(isset($options['key']) && isset($options['iv']))) {
\Log::error("Either key or iv not set");
throw new \Exception("Either key or iv not set");
}
Session::put('aes_key', $options['key']);
Session::put('aes_iv', $options['iv']);
$aes = new \Crypt_AES(CRYPT_AES_MODE_CBC);
$aes->setKeyLength(256);
$aes->setKey(Base64::UrlDecode($options['key']));
$aes->setIV(Base64::UrlDecode($options['iv']));
$aes->enablePadding();
$this->aes = $aes;
$this->isAesInitialized = true;
}
示例5: urlencode
}
###
$return = 'boxgamefile.php?id=' . urlencode($boxid);
require "../configuration.php";
require "./include.php";
require_once "../includes/func.ssh2.inc.php";
require_once "../libs/phpseclib/Crypt/AES.php";
require_once "../libs/gameinstaller/gameinstaller.php";
$title = T_('Box Game File Repositories');
if (query_numrows("SELECT `name` FROM `" . DBPREFIX . "box` WHERE `boxid` = '" . $boxid . "'") == 0) {
exit('Error: BoxID is invalid.');
}
$rows = query_fetch_assoc("SELECT * FROM `" . DBPREFIX . "box` WHERE `boxid` = '" . $boxid . "' LIMIT 1");
$games = mysql_query("SELECT * FROM `" . DBPREFIX . "game` ORDER BY `game`");
$aes = new Crypt_AES();
$aes->setKeyLength(256);
$aes->setKey(CRYPT_KEY);
// Get SSH2 Object OR ERROR String
$ssh = newNetSSH2($rows['ip'], $rows['sshport'], $rows['login'], $aes->decrypt($rows['password']));
if (!is_object($ssh)) {
$_SESSION['msg1'] = T_('Connection Error!');
$_SESSION['msg2'] = $ssh;
$_SESSION['msg-type'] = 'error';
}
$gameInstaller = new GameInstaller($ssh);
include "./bootstrap/header.php";
/**
* Notifications
*/
include "./bootstrap/notifications.php";
?>
示例6: getPassword
function getPassword($pwd = null, $iv_field = "iv")
{
if (is_null($pwd)) {
$pwd = $this->password;
if (!$this->password) {
return "";
}
}
try {
$master_key_filepath = CAppUI::conf("master_key_filepath");
$master_key_filepath = rtrim($master_key_filepath, "/");
if (CExchangeSource::checkMasterKeyFile($master_key_filepath)) {
CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/AES");
CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/Random");
$cipher = new Crypt_AES(CRYPT_AES_MODE_CTR);
$cipher->setKeyLength(256);
$keyAB = file($master_key_filepath . "/.mediboard.key");
if (count($keyAB) == 2) {
$cipher->setKey($keyAB[0] . $keyAB[1]);
$ivToUse = $this->{$iv_field};
if (!$ivToUse) {
$clear = $pwd;
$this->store();
return $clear;
}
$cipher->setIV($ivToUse);
$decrypted = rtrim(base64_decode($pwd), "");
$decrypted = $cipher->decrypt($decrypted);
if ($decrypted) {
return $decrypted;
}
}
}
} catch (Exception $e) {
return $pwd;
}
return $pwd;
}
示例7: decryptSessionCredentials
/**
* Decrypt Session Credentials
*
* @param none
* @return array
* @access private
*/
private function decryptSessionCredentials()
{
if (!empty($this->session) && array_key_exists('CREDENTIALS', $this->session)) {
switch (CONF_SEC_SESSION_METHOD) {
case 'aes256':
default:
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
$cipher->setKeyLength(256);
$cipher->setKey($this->session_key);
$credentials = unserialize($cipher->decrypt($this->session['CREDENTIALS']));
break;
}
return $credentials;
}
return array();
}
示例8: getCipher
public static function getCipher($algo)
{
$cipher = null;
switch ($algo) {
case 2:
if (class_exists('Crypt_TripleDES')) {
$cipher = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
$key_bytes = 24;
$key_block_bytes = 8;
}
break;
case 3:
if (defined('MCRYPT_CAST_128')) {
$cipher = new MCryptWrapper(MCRYPT_CAST_128);
}
break;
case 7:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(128);
}
break;
case 8:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(192);
}
break;
case 9:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(256);
}
break;
}
if (!$cipher) {
return array(null, null, null);
// Unsupported cipher
}
if (!isset($key_bytes)) {
$key_bytes = $cipher->key_size;
}
if (!isset($key_block_bytes)) {
$key_block_bytes = $cipher->block_size;
}
return array($cipher, $key_bytes, $key_block_bytes);
}
示例9: authenticateThenDecrypt
/**
* Validate the signature and date of the message, then
* decrypt it.
*
* @param string $secret
* @param string $body
* @param string $signature
* @return string
* Plain text.
* @throws InvalidMessageException
*/
public static function authenticateThenDecrypt($secret, $body, $signature)
{
$keys = self::deriveAesKeys($secret);
$localHmac = hash_hmac('sha256', $body, $keys['auth']);
if (!self::hash_compare($signature, $localHmac)) {
throw new InvalidMessageException("Incorrect hash");
}
list($jsonEnvelope, $jsonEncrypted) = explode(Constants::PROTOCOL_DELIM, $body, 2);
if (strlen($jsonEnvelope) > Constants::MAX_ENVELOPE_BYTES) {
throw new InvalidMessageException("Oversized envelope");
}
$envelope = json_decode($jsonEnvelope, TRUE);
if (!$envelope) {
throw new InvalidMessageException("Malformed envelope");
}
if (!is_numeric($envelope['ttl']) || Time::getTime() > $envelope['ttl']) {
throw new InvalidMessageException("Invalid TTL");
}
if (!is_string($envelope['iv']) || strlen($envelope['iv']) !== Constants::AES_BYTES * 2 || !preg_match('/^[a-f0-9]+$/', $envelope['iv'])) {
// AES_BYTES (32) ==> bin2hex ==> 2 hex digits (4-bit) per byte (8-bit)
throw new InvalidMessageException("Malformed initialization vector");
}
$jsonPlaintext = UserError::adapt('Civi\\Cxn\\Rpc\\Exception\\InvalidMessageException', function () use($jsonEncrypted, $envelope, $keys) {
$cipher = new \Crypt_AES(CRYPT_AES_MODE_CBC);
$cipher->setKeyLength(Constants::AES_BYTES);
$cipher->setKey($keys['enc']);
$cipher->setIV(BinHex::hex2bin($envelope['iv']));
return $cipher->decrypt($jsonEncrypted);
});
return $jsonPlaintext;
}
示例10: SendEncryptedResponse
function SendEncryptedResponse($message)
{
$aes = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aes->setKeyLength(256);
$aes->setKey(Base64UrlDecode($_SESSION['key']));
$aes->setIV(Base64UrlDecode($_SESSION['iv']));
$aes->enablePadding();
// This is PKCS
echo Base64UrlEncode($aes->encrypt($message));
exit;
}
示例11: postBox
//.........这里部分代码省略.........
$sth->bindParam(':box_id', $box_id);
$sth->bindParam(':ip', $args['ip']);
$sth->execute();
} catch (PDOException $e) {
echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
die;
}
// CREDENTIALS
// Phase 1
// Connect to the remote host
// Try to append our public key to authorized_keys
$ssh = new Net_SSH2($args['ip'], $args['port']);
$ssh->login($args['login'], $args['password']);
$remote_keys = $ssh->exec('cat ' . $home . '/.ssh/authorized_keys');
// Check if the public key already exists
if (strpos($remote_keys, file_get_contents(RSA_PUBLIC_KEY_FILE)) === FALSE) {
// Otherwise, append it
$ssh->exec("echo '" . file_get_contents(RSA_PUBLIC_KEY_FILE) . "' >> " . $home . "/.ssh/authorized_keys");
}
// Phase 2
// Verify that the public key is allowed on the remote host
$isUsingSSHPubKey = TRUE;
// By default, we use the SSH authentication keys method
$remote_keys = $ssh->exec('cat ' . $home . '/.ssh/authorized_keys');
$ssh->disconnect();
if (strpos($remote_keys, file_get_contents(RSA_PUBLIC_KEY_FILE)) === FALSE) {
// authorized_keys is not writable
// Use compatibility mode
// Store the password in DB
$isUsingSSHPubKey = FALSE;
} else {
// Phase 3
// Try to connect with our private key on the remote host
$ssh = new Net_SSH2($args['ip'], $args['port']);
$key = new Crypt_RSA();
$key->loadKey(file_get_contents(RSA_PRIVATE_KEY_FILE));
if (!$ssh->login($args['login'], $key)) {
// Authentication failed
// Use compatibility mode
// Store the password in DB
$isUsingSSHPubKey = FALSE;
}
$ssh->disconnect();
}
// SSH CREDENTIALS
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
$cipher->setKeyLength(256);
$cipher->setKey($config['APP_SSH_KEY']);
if ($isUsingSSHPubKey) {
try {
$sth = $dbh->prepare("\n\t\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box_credential\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\tlogin = :login,\n\t\t\t\t\t\t\tremote_user_home = :home,\n\t\t\t\t\t\t\tcom_protocol = 'ssh2',\n\t\t\t\t\t\t\tcom_port = :com_port\n\t\t\t\t\t\t;");
$login = $cipher->encrypt($args['login']);
$sth->bindParam(':login', $login);
$sth->bindParam(':home', $args['userPath']);
$sth->bindParam(':com_port', $args['port']);
$sth->execute();
$credential_id = $dbh->lastInsertId();
} catch (PDOException $e) {
echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
die;
}
} else {
try {
$sth = $dbh->prepare("\n\t\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box_credential\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\tlogin = :login,\n\t\t\t\t\t\t\tpassword = :password,\n\t\t\t\t\t\t\tremote_user_home = :home,\n\t\t\t\t\t\t\tcom_protocol = 'ssh2',\n\t\t\t\t\t\t\tcom_port = :port\n\t\t\t\t\t\t;");
$login = $cipher->encrypt($args['login']);
$password = $cipher->encrypt($args['password']);
$sth->bindParam(':login', $login);
$sth->bindParam(':password', $password);
$sth->bindParam(':home', $args['userPath']);
$sth->bindParam(':com_port', $args['port']);
$sth->execute();
$credential_id = $dbh->lastInsertId();
} catch (PDOException $e) {
echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
die;
}
}
// UPDATE BOX
try {
$sth = $dbh->prepare("\n\t\t\t\t\tUPDATE " . DB_PREFIX . "box\n\t\t\t\t\tSET\n\t\t\t\t\t\tbox_credential_id = :box_credential_id\n\t\t\t\t\tWHERE box_id = :box_id\n\t\t\t\t\t;");
$sth->bindParam(':box_credential_id', $credential_id);
$sth->bindParam(':box_id', $box_id);
$sth->execute();
} catch (PDOException $e) {
echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
die;
}
}
// return a response and log ===================================================
$logger = self::getLogger();
$data['errors'] = $errors;
if (!empty($data['errors'])) {
$data['success'] = false;
$logger->info('Failed to add box.');
} else {
$data['success'] = true;
$logger->info('Box added.');
}
return array('response' => 'application/json', 'data' => json_encode($data));
}
示例12: onStartMagicEnvelopeToXML
public function onStartMagicEnvelopeToXML(MagicEnvelope $magic_env, XMLStringer $xs, $flavour = null, Profile $target = null)
{
// Since Diaspora doesn't use a separate namespace for their "extended"
// salmon slap, we'll have to resort to this workaround hack.
if ($flavour !== 'diaspora') {
return true;
}
// WARNING: This changes the $magic_env contents! Be aware of it.
/**
* https://wiki.diasporafoundation.org/Federation_protocol_overview
* http://www.rubydoc.info/github/Raven24/diaspora-federation/master/DiasporaFederation/Salmon/EncryptedSlap
*
* Constructing the encryption header
*/
// For some reason diaspora wants the salmon slap in a <diaspora> header.
$xs->elementStart('diaspora', array('xmlns' => 'https://joindiaspora.com/protocol'));
/**
* Choose an AES key and initialization vector, suitable for the
* aes-256-cbc cipher. I shall refer to this as the “inner key”
* and the “inner initialization vector (iv)”.
*/
$inner_key = new Crypt_AES(CRYPT_AES_MODE_CBC);
$inner_key->setKeyLength(256);
// set length to 256 bits (could be calculated, but let's be sure)
$inner_key->setKey(common_random_rawstr(32));
// 32 bytes from a (pseudo) random source
$inner_key->setIV(common_random_rawstr(16));
// 16 bytes is the block length
/**
* Construct the following XML snippet:
* <decrypted_header>
* <iv>((base64-encoded inner iv))</iv>
* <aes_key>((base64-encoded inner key))</aes_key>
* <author>
* <name>Alice Exampleman</name>
* <uri>acct:user@sender.example</uri>
* </author>
* </decrypted_header>
*/
$decrypted_header = sprintf('<decrypted_header><iv>%1$s</iv><aes_key>%2$s</aes_key><author_id>%3$s</author_id></decrypted_header>', base64_encode($inner_key->iv), base64_encode($inner_key->key), $magic_env->getActor()->getAcctUri());
/**
* Construct another AES key and initialization vector suitable
* for the aes-256-cbc cipher. I shall refer to this as the
* “outer key” and the “outer initialization vector (iv)”.
*/
$outer_key = new Crypt_AES(CRYPT_AES_MODE_CBC);
$outer_key->setKeyLength(256);
// set length to 256 bits (could be calculated, but let's be sure)
$outer_key->setKey(common_random_rawstr(32));
// 32 bytes from a (pseudo) random source
$outer_key->setIV(common_random_rawstr(16));
// 16 bytes is the block length
/**
* Encrypt your <decrypted_header> XML snippet using the “outer key”
* and “outer iv” (using the aes-256-cbc cipher). This encrypted
* blob shall be referred to as “the ciphertext”.
*/
$ciphertext = $outer_key->encrypt($decrypted_header);
/**
* Construct the following JSON object, which shall be referred to
* as “the outer aes key bundle”:
* {
* "iv": ((base64-encoded AES outer iv)),
* "key": ((base64-encoded AES outer key))
* }
*/
$outer_bundle = json_encode(array('iv' => base64_encode($outer_key->iv), 'key' => base64_encode($outer_key->key)));
/**
* Encrypt the “outer aes key bundle” with Bob’s RSA public key.
* I shall refer to this as the “encrypted outer aes key bundle”.
*/
common_debug('Diaspora creating "outer aes key bundle", will require magic-public-key');
$key_fetcher = new MagicEnvelope();
$remote_keys = $key_fetcher->getKeyPair($target, true);
// actually just gets the public key
$enc_outer = $remote_keys->publicKey->encrypt($outer_bundle);
/**
* Construct the following JSON object, which I shall refer to as
* the “encrypted header json object”:
* {
* "aes_key": ((base64-encoded encrypted outer aes key bundle)),
* "ciphertext": ((base64-encoded ciphertextm from above))
* }
*/
$enc_header = json_encode(array('aes_key' => base64_encode($enc_outer), 'ciphertext' => base64_encode($ciphertext)));
/**
* Construct the xml snippet:
* <encrypted_header>((base64-encoded encrypted header json object))</encrypted_header>
*/
$xs->element('encrypted_header', null, base64_encode($enc_header));
/**
* In order to prepare the payload message for inclusion in your
* salmon slap, you will:
*
* 1. Encrypt the payload message using the aes-256-cbc cipher and
* the “inner encryption key” and “inner encryption iv” you
* chose earlier.
* 2. Base64-encode the encrypted payload message.
*/
$payload = $inner_key->encrypt($magic_env->getData());
//.........这里部分代码省略.........
示例13: getCipher
public static function getCipher($algo)
{
$cipher = NULL;
switch ($algo) {
case 2:
if (class_exists('Crypt_TripleDES')) {
$cipher = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
$key_bytes = 24;
$key_block_bytes = 8;
}
break;
case 3:
if (defined('MCRYPT_CAST_128')) {
$cipher = new MCryptWrapper(MCRYPT_CAST_128);
} else {
$cipher = new Horde_Pgp_Crypt_Cast128();
}
/* End Horde Change */
break;
/* Horde change */
/* Horde change */
case 4:
$cipher = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CFB);
$key_bytes = 16;
break;
/* End Horde Change */
/* End Horde Change */
case 7:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(128);
}
break;
case 8:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(192);
}
break;
case 9:
if (class_exists('Crypt_AES')) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(256);
}
break;
/* Horde change */
/* Horde change */
case 10:
$cipher = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CFB);
$key_bytes = 32;
break;
/* End Horde Change */
}
if (!$cipher) {
return array(NULL, NULL, NULL);
}
// Unsupported cipher
if (!isset($key_bytes)) {
$key_bytes = $cipher->key_size;
}
if (!isset($key_block_bytes)) {
$key_block_bytes = $cipher->block_size;
}
return array($cipher, $key_bytes, $key_block_bytes);
}
示例14: generateKey
/**
*/
public function generateKey($opts)
{
$skey = $this->_generateSecretKeyPacket($opts['keylength'], 'OpenPGP_SecretKeyPacket');
$id = new Horde_Mail_Rfc822_Address($opts['email']);
if (strlen($opts['comment'])) {
$id->comment[] = $opts['comment'];
}
if (strlen($opts['name'])) {
$id->personal = $opts['name'];
}
/* This is the private key we are creating. */
$key = new OpenPGP_Message(array($skey, new OpenPGP_UserIDPacket($id->writeAddress(array('comment' => true)))));
$rsa = OpenPGP_Crypt_RSA::convert_private_key($skey);
$rsa->setHash(Horde_String::lower($opts['hash']));
$rsa_sign_func = array('RSA' => array($opts['hash'] => function ($data) use($rsa) {
return array($rsa->sign($data));
}));
/* Create signature packet. */
$sig = new OpenPGP_SignaturePacket($key, 'RSA', $opts['hash']);
/* "Generic certification of a User ID and Public-Key packet." */
$sig->signature_type = 0x10;
/* Add subpacket information. */
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyFlagsPacket(array(0x3));
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredSymmetricAlgorithmsPacket(array(0x9, 0x8, 0x7, 0x2));
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredHashAlgorithmsPacket(array(0x8, 0x9, 0xa, 0xb, 0x2));
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredCompressionAlgorithmsPacket(array(0x2, 0x1));
$ks_prefs = new OpenPGP_SignaturePacket_KeyServerPreferencesPacket();
$ks_prefs->no_modify = true;
$sig->hashed_subpackets[] = $ks_prefs;
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_FeaturesPacket(array(0x1));
if (isset($opts['expire'])) {
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyExpirationTimePacket($opts['expire'] - time());
}
$sig->unhashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket(substr($skey->fingerprint, -16));
$key[] = $sig;
/* Create self-signature. */
$sig->sign_data($rsa_sign_func);
/* OpenPGP currently (as of April 2015) encrypts passphrases w/
* AES-128 & SHA-1, so use this strategy. */
if (strlen($opts['passphrase'])) {
$cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
$cipher->setKeyLength(128);
$s2k = new OpenPGP_S2K(crypt_random_string(8), 2);
$cipher->setKey($s2k->make_key($opts['passphrase'], 16));
$iv = crypt_random_string(16);
$this->_encryptPrivateKey($skey, $cipher, $s2k, $iv);
}
/* Encryption subkey. See RFC 4880 [5.5.1.2] (by convention, top-level
* key is used for signing and subkeys are used for encryption) */
$ekey = $this->_generateSecretKeyPacket($opts['keylength'], 'OpenPGP_SecretSubkeyPacket');
/* Computing signature: RFC 4880 [5.2.4] */
$sig = new OpenPGP_SignaturePacket(implode('', $skey->fingerprint_material()) . implode('', $ekey->fingerprint_material()), 'RSA', $opts['hash']);
/* This is a "Subkey Binding Signature". */
$sig->signature_type = 0x18;
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyFlagsPacket(array(0xc));
$sig->unhashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket(substr($skey->fingerprint, -16));
$sig->sign_data($rsa_sign_func);
if (strlen($opts['passphrase'])) {
$this->_encryptPrivateKey($ekey, $cipher, $s2k, $iv);
}
$key[] = $ekey;
$key[] = $sig;
return new Horde_Pgp_Element_PrivateKey($key);
}