use std::fs;
use pgp::{
composed::{Deserializable, Message, MessageBuilder, SignedPublicKey, SignedSecretKey},
crypto::sym::SymmetricKeyAlgorithm,
types::KeyDetails,
};
use rand::thread_rng;
fn main() {
let encrypted = {
let msg = b"Secret message";
let public_key = read_public_key(&fs::read("example-key.pub").expect("public key"));
encrypt(&public_key, msg)
};
let secret_key = read_secret_key(&fs::read("example-key.priv").expect("secret key"));
let decrypted = decrypt(&secret_key, &encrypted);
println!("Decrypted message:");
println!("'{}'", String::from_utf8(decrypted).expect("UTF-8"));
}
fn encrypt(cert: &SignedPublicKey, msg: &[u8]) -> Vec<u8> {
let encryption_subkey = &cert.public_subkeys[1];
assert!(
encryption_subkey.algorithm().can_encrypt(),
"Unexpected subkey layout"
);
let mut builder = MessageBuilder::from_bytes("", msg.to_vec())
.seipd_v1(thread_rng(), SymmetricKeyAlgorithm::AES256);
builder
.encrypt_to_key(thread_rng(), &encryption_subkey)
.unwrap();
builder.to_vec(thread_rng()).unwrap()
}
fn decrypt(ssk: &SignedSecretKey, msg: &[u8]) -> Vec<u8> {
let mut decrypted = Message::from_bytes(msg)
.expect("parse message")
.decrypt(&"".into(), ssk)
.expect("decrypt message");
if decrypted.is_compressed() {
decrypted = decrypted.decompress().expect("Message decompress");
}
decrypted.as_data_vec().expect("Message as data")
}
pub fn read_secret_key(input: &[u8]) -> SignedSecretKey {
let (key, _headers) = SignedSecretKey::from_reader_single(input).unwrap();
key.verify_bindings().expect("Verify key");
key
}
pub fn read_public_key(input: &[u8]) -> SignedPublicKey {
let (cert, _headers) = SignedPublicKey::from_reader_single(input).unwrap();
cert.verify_bindings().expect("Verify cert");
cert
}