Can't decrypt Message encrypted with multiple public keys.
ovxrfl0w opened this issue · 2 comments
Hello there!
I am having a problem with decrypting an OpenPGP message encrypted with multiple public keys.
public function encrypt($plaintext, $users = array())
{
$query = $this->db->prepare("SELECT * FROM users WHERE username=:u");
$query->execute(array(":u" => "admin"));
$adminKey = null;
if ($query->rowCount() > 0) {
$adminKey = $query->fetch(PDO::FETCH_OBJ)->publicKey;
} else {
$publicKey = "./keys/admin_pub.asc";
if (File::Exists($publicKey)) {
$adminKey = File::ReadFile($publicKey);
}
}
if ($adminKey != null) {
$key = OpenPGP_Message::parse(OpenPGP::unarmor($adminKey, 'TEST PUBLIC KEY'));
$keys = array();
array_push($keys, $key);
foreach ($users as $user) {
$ukey = OpenPGP_Message::parse(OpenPGP::unarmor($user->getKey(), 'TEST PUBLIC KEY'));
array_push($keys, $ukey);
}
$data = new OpenPGP_LiteralDataPacket($plaintext);
$encrypted = OpenPGP_Crypt_Symmetric::encrypt($keys, new OpenPGP_Message(array($data)));
$message = OpenPGP::enarmor($encrypted->to_bytes(), 'PGP MESSAGE');
return $message;
} else {
return false;
}
}
public function decrypt($encrypted)
{
$keyData = File::ReadFile("./keys/admin_priv.asc");
$msgEncrypted = OpenPGP_Message::parse(OpenPGP::unarmor($encrypted, 'PGP MESSAGE'));
var_dump($msgEncrypted);
$key = OpenPGP_Message::parse(OpenPGP::unarmor($keyData, 'TEST PRIVATE KEY'));
$decryptor = new OpenPGP_Crypt_RSA($key);
$decrypted = $decryptor->decrypt($msgEncrypted)->packets[0]->data;
if ($decrypted) {
return $decrypted;
}
return false;
}
basically, I can decrypt the message if I just pass the $key object (which is the admin's public key) but not when I pass an array of keys ($keys)
Here is the response with the encrypted message
ENCRYPTED
-----BEGIN PGP MESSAGE-----
0v8AAABFAT+o754UMF64zgvaaaiBR/wmv+SeI4FHgoI6prH7dy8c+jDxjyd/atzYAekjfUzzqz2I
TWFOt+ZiBgzdA+6xp7h86mxL
=Q0hl
-----END PGP MESSAGE-----
object(OpenPGP_Message)#40 (2) { ["uri"]=> NULL ["packets"]=> array(1) { [0]=> object(OpenPGP_IntegrityProtectedDataPacket)#38 (4) { ["version"]=> int(1) ["tag"]=> int(18) ["size"]=> NULL ["data"]=> string(68) "?���0^����i��G�&��#�G��:���w/��0�'�j����#}L�=�MaN��b����|�lK" } } } CAN'T DECRYPT
Tried changing the keys from the OpenPGP_Message object to a string but I am still not able to decrypt it. Even tried passing the keys just with OpenPGP::unarmor($key, 'TEST PUBLIC KEY');
I fixed this issue by passing an array of packets instead of an array of OpenPGP_Message objects.
$key = OpenPGP_Message::parse(OpenPGP::unarmor($adminKey, "TEST PUBLIC KEY"));
$keys = array();
foreach ($key as $packets) {
array_push($keys, $packets);
}
foreach ($users as $user) {
$ukey = OpenPGP_Message::parse(OpenPGP::unarmor($user->getKey(), "TEST PUBLIC KEY"));
foreach ($ukey as $uPackets) {
array_push($keys, $uPackets);
}
}
$data = new OpenPGP_LiteralDataPacket($plaintext);
$encrypted = OpenPGP_Crypt_Symmetric::encrypt($keys, new OpenPGP_Message(array($data)));
$message = OpenPGP::enarmor($encrypted->to_bytes(), "ENCRYPTED MESSAGE");
return $message;
In the code above I am passing $users to the function running this code which is my custom object and getKey function returns the ASCII armored public key.
- $key = sender key (my admin key)
- $packets = sender key packets (packets of $key)
- $ukey = user key
- $uPackets = user key packets (packets of $ukey)
- $keys = array of all packets ($packets, $uPackets...)
Huge thanks to @singpolyma for helping me fix this issue.