pub struct Encryptor<W> { /* private fields */ }Expand description
A Write adapter that encrypts a ZipCrypto entry on the fly.
On construction it emits the 12-byte encryption header; writes then encrypt the (already compressed) body.
The encryption header includes a single check byte for a cheap reader-side
password test. rawzip always emits a data descriptor, so it is the high byte
of the entry’s DOS mod time (see Encryptor::new).
§Examples
let password = b"rawzipiscool";
let mut output = std::io::Cursor::new(Vec::new());
let mut archive = ZipArchiveWriter::new(&mut output);
let (mut entry, config) = archive
.new_file("test.txt")
.compression_method(CompressionMethod::DEFLATE)
.encrypted(true)
.start()?;
// In production these 11 bytes must come from a cryptographic RNG.
let header_random = [0u8; 11];
// rawzip always writes a data descriptor, so the check byte is the high
// byte of the DOS mod time.
let check_byte = (entry.last_modified_dos().packed_time() >> 8) as u8;
let encryptor = Encryptor::new(&mut entry, password, header_random, check_byte)?;
let deflater = flate2::write::DeflateEncoder::new(encryptor, flate2::Compression::default());
let mut writer = config.wrap(deflater);
writer.write_all(b"aaaaaaaaaaaaaaaa\n")?;
let (deflater, descriptor) = writer.finish()?;
deflater.finish()?; // drops the encryptor, releasing the borrow on `entry`
entry.finish(descriptor)?;
archive.finish()?;
// Round-trips back through the reader.
let zip = output.into_inner();
let archive = ZipArchive::from_slice(&zip)?;
let entry = archive.entries().next().unwrap()?;
let zip_entry = archive.get_entry(entry.wayfinder())?;
let decryptor = Decryptor::new(zip_entry.data(), password)?;
let inflater = flate2::read::DeflateDecoder::new(decryptor);
let mut decoded = Vec::new();
zip_entry.verifying_reader(inflater).read_to_end(&mut decoded)?;
assert_eq!(decoded, b"aaaaaaaaaaaaaaaa\n");Implementations§
Source§impl<W: Write> Encryptor<W>
impl<W: Write> Encryptor<W>
Sourcepub fn new(
writer: W,
password: &[u8],
header_random: [u8; 11],
check_byte: u8,
) -> Result<Self>
pub fn new( writer: W, password: &[u8], header_random: [u8; 11], check_byte: u8, ) -> Result<Self>
Wraps a writer positioned at the start of an entry’s body, emitting the encrypted 12-byte encryption header.
header_random are the 11 leading header bytes. They are security-only:
any values produce a valid, round-trippable archive, but reusing them
across entries under the same password leaks information, so draw them
from a cryptographic RNG in production.
check_byte is the 1-in-256 password verifier the reader checks: the
high byte of the entry’s CRC32, or of its DOS mod time when the entry
carries a data descriptor (general purpose bit 3). rawzip’s writer always
sets that bit, so for its entries compute it as
(entry.last_modified_dos().packed_time() >> 8) as u8.
Sourcepub fn into_inner(self) -> W
pub fn into_inner(self) -> W
Consumes the encryptor, returning the wrapped writer.
Trait Implementations§
Source§impl<W: Write> Write for Encryptor<W>
impl<W: Write> Write for Encryptor<W>
Source§fn write(&mut self, buf: &[u8]) -> Result<usize>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
Source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored)