Ejemplo n.º 1
0
 /**
  * Transform key
  *
  * @param  info.keepass.Header $header
  * @return string
  */
 public function transform($header)
 {
     $hash = hash(self::ALGORITHM, hash(self::ALGORITHM, $this->passphrase->reveal(), true), true);
     // Rounds is a 64-bit integer, which cannot be handled by PHP. Use the
     // four 16-bit unsigned ints into ones, tens and hundreds, then iterate.
     $rounds = $header->rounds;
     $ones = $rounds[0] | ($rounds[1] & 0x3fff) << 0x10;
     $tens = ($rounds[1] & 0xc000) >> 0xe | $rounds[2] << 0x2 | ($rounds[3] & 0xfff) << 0x12;
     $hundreds = ($rounds[3] & 0xf000) >> 0xc;
     $cipher = new Cipher('aes-256-ecb', $header->transformSeed, '');
     do {
         $hash = $cipher->encrypt($hash, $ones);
         if ($tens > 0) {
             $tens--;
             $ones = 0x40000000;
         } else {
             if ($hundreds > 0) {
                 $hundreds--;
                 $tens = 0x3fffffff;
                 $ones = 0x40000000;
             } else {
                 $ones = 0;
             }
         }
     } while ($ones);
     return hash(self::ALGORITHM, $header->masterSeed . hash(self::ALGORITHM, $hash, true), true);
 }
Ejemplo n.º 2
0
 /**
  * Opens a KeePass database file
  *
  * @param  io.streams.InputStream $input
  * @param  info.keepass.Key $key
  * @return self
  * @throws lang.FormatException
  * @throws info.keepass.CannotDecrypt
  */
 public static function open($input, Key $key)
 {
     $self = new self();
     with(new Reader($input, 'sha256'), function ($reader) use($self, $key) {
         $self->version = $reader->version();
         $self->header = $reader->header();
         $cipher = new Cipher($self->header->algorithm(), $key->transform($self->header), $self->header->encryptionIV);
         $decrypted = $cipher->decrypt($reader->remaining());
         $start = strlen($self->header->startBytes);
         if (0 !== strncmp($decrypted, $self->header->startBytes, $start)) {
             throw new CannotDecrypt('Incorrect passphrase?');
         }
         $self->blocks = new Blocks($decrypted, $start);
     });
     return $self;
 }