Decrypt secret key
This commit is contained in:
parent
ae062433b7
commit
a56799955f
@ -1454,15 +1454,15 @@ class OpenPGP_PublicSubkeyPacket extends OpenPGP_PublicKeyPacket {
|
||||
* @see http://tools.ietf.org/html/rfc4880#section-12
|
||||
*/
|
||||
class OpenPGP_SecretKeyPacket extends OpenPGP_PublicKeyPacket {
|
||||
public $s2k_useage, $s2k, $symmetric_type, $private_hash, $encrypted_data;
|
||||
public $s2k_useage, $s2k, $symmetric_algorithm, $private_hash, $encrypted_data;
|
||||
function read() {
|
||||
parent::read(); // All the fields from PublicKey
|
||||
$this->s2k_useage = ord($this->read_byte());
|
||||
if($this->s2k_useage == 255 || $this->s2k_useage == 254) {
|
||||
$this->symmetric_type = ord($this->read_byte());
|
||||
$this->symmetric_algorithm = ord($this->read_byte());
|
||||
$this->s2k = OpenPGP_S2k::parse($this->input);
|
||||
} else if($this->s2k_useage > 0) {
|
||||
$this->symmetric_type = $this->s2k_useage;
|
||||
$this->symmetric_algorithm = $this->s2k_useage;
|
||||
}
|
||||
if($this->s2k_useage > 0) {
|
||||
// TODO: IV of the same length as cipher's block size
|
||||
@ -1503,7 +1503,7 @@ class OpenPGP_SecretKeyPacket extends OpenPGP_PublicKeyPacket {
|
||||
$bytes = parent::body() . chr($this->s2k_useage);
|
||||
$secret_material = NULL;
|
||||
if($this->s2k_useage == 255 || $this->s2k_useage == 254) {
|
||||
$bytes .= chr($this->symmetric_type);
|
||||
$bytes .= chr($this->symmetric_algorithm);
|
||||
$bytes .= $this->s2k->to_bytes();
|
||||
}
|
||||
if($this->s2k_useage > 0) {
|
||||
|
@ -30,6 +30,44 @@ class OpenPGP_Crypt_AES_TripleDES {
|
||||
return NULL; /* If we get here, we failed */
|
||||
}
|
||||
|
||||
public static function decryptSecretKey($pass, $packet) {
|
||||
$packet = clone $packet; // Do not mutate orinigal
|
||||
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($packet->symmetric_algorithm);
|
||||
$cipher->setKey($packet->s2k->make_key($pass, $key_bytes));
|
||||
$cipher->setIV(substr($packet->encrypted_data, 0, $key_block_bytes));
|
||||
$material = $cipher->decrypt(substr($packet->encrypted_data, $key_block_bytes));
|
||||
|
||||
if($packet->s2k_useage == 254) {
|
||||
$chk = substr($material, -20);
|
||||
$material = substr($material, 0, -20);
|
||||
if($chk != hash('sha1', $material)) return NULL;
|
||||
} else {
|
||||
$chk = unpack('n', substr($material, -2));
|
||||
$chk = reset($chk);
|
||||
$material = substr($material, 0, -2);
|
||||
|
||||
$mkChk = 0;
|
||||
for($i = 0; $i < strlen($material); $i++) {
|
||||
$mkChk = ($mkChk + ord($material{$i})) % 65536;
|
||||
}
|
||||
if($chk != $mkChk) return NULL;
|
||||
}
|
||||
|
||||
$packet->s2k_useage = 0;
|
||||
$packet->symmetric_algorithm = 0;
|
||||
$packet->encrypted_data = NULL;
|
||||
|
||||
foreach($packet::$secret_key_fields[$packet->algorithm] as $f) {
|
||||
$length = unpack('n', substr($material, 0, 2)); // in bits
|
||||
$length = (int)floor((reset($length) + 7) / 8); // in bytes
|
||||
$packet->key[$f] = substr($material, 2, $length);
|
||||
$material = substr($material, 2 + $length);
|
||||
}
|
||||
|
||||
return $packet;
|
||||
}
|
||||
|
||||
public static function decryptPacket($epacket, $symmetric_algorithm, $key) {
|
||||
list($cipher, $key_bytes, $key_block_bytes) = self::getCipher($symmetric_algorithm);
|
||||
if(!$cipher) return NULL;
|
||||
|
BIN
tests/data/encryptedSecretKey.gpg
Normal file
BIN
tests/data/encryptedSecretKey.gpg
Normal file
Binary file not shown.
@ -104,4 +104,10 @@ class Decryption extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testDecryptSecretKey() {
|
||||
$key = OpenPGP_Message::parse(file_get_contents(dirname(__FILE__) . '/data/encryptedSecretKey.gpg'));
|
||||
$skey = OpenPGP_Crypt_AES_TripleDES::decryptSecretKey("hello", $key[0]);
|
||||
$this->assertSame(!!$skey, true);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user