create static method
Implementation
static UPdfEncryption? create(UPdfDict encrypt, Uint8List firstId, String password) {
final Object? filterName = encrypt["Filter"];
if (filterName is UPdfName && filterName.value != "Standard") return null;
final int version = (encrypt["V"] as num?)?.toInt() ?? 0;
final int revision = (encrypt["R"] as num?)?.toInt() ?? 2;
final int bits = (encrypt["Length"] as num?)?.toInt() ?? 40;
final int permissionFlags = (encrypt["P"] as num?)?.toInt() ?? -1;
final bool encryptMetadata = encrypt["EncryptMetadata"] as bool? ?? true;
final Uint8List owner = encrypt["O"] is UPdfString ? (encrypt["O"]! as UPdfString).bytes : Uint8List(0);
final Uint8List user = encrypt["U"] is UPdfString ? (encrypt["U"]! as UPdfString).bytes : Uint8List(0);
final UPdfDict? filters = encrypt["CF"] is UPdfDict ? encrypt["CF"]! as UPdfDict : null;
final UPdfCryptMethod streamMethod = _methodFor(filters, encrypt["StmF"], version);
final UPdfCryptMethod stringMethod = _methodFor(filters, encrypt["StrF"], version);
final List<int> passwordBytes = utf8.encode(password);
if (revision >= 5) {
final Uint8List ownerExtra = encrypt["OE"] is UPdfString ? (encrypt["OE"]! as UPdfString).bytes : Uint8List(0);
final Uint8List userExtra = encrypt["UE"] is UPdfString ? (encrypt["UE"]! as UPdfString).bytes : Uint8List(0);
final _UPdfV5Result? result = _authenticateV5(passwordBytes, owner, user, ownerExtra, userExtra, revision);
if (result == null) {
return UPdfEncryption._(
revision: revision,
version: version,
keyLength: 32,
streamMethod: streamMethod,
stringMethod: stringMethod,
fileKey: Uint8List(0),
permissionFlags: permissionFlags,
authenticated: false,
ownerAuthenticated: false,
encryptMetadata: encryptMetadata,
);
}
return UPdfEncryption._(
revision: revision,
version: version,
keyLength: 32,
streamMethod: streamMethod,
stringMethod: stringMethod,
fileKey: result.key,
permissionFlags: permissionFlags,
authenticated: true,
ownerAuthenticated: result.owner,
encryptMetadata: encryptMetadata,
);
}
final int keyLength = version == 1 ? 5 : (bits ~/ 8).clamp(5, 16);
Uint8List key = _legacyKey(passwordBytes, owner, permissionFlags, firstId, revision, keyLength, encryptMetadata);
bool authenticated = _checkUser(key, user, firstId, revision);
bool ownerAuthenticated = false;
if (!authenticated) {
final List<int>? recovered = _recoverUserPassword(passwordBytes, owner, revision, keyLength);
if (recovered != null) {
final Uint8List ownerKey = _legacyKey(recovered, owner, permissionFlags, firstId, revision, keyLength, encryptMetadata);
if (_checkUser(ownerKey, user, firstId, revision)) {
key = ownerKey;
authenticated = true;
ownerAuthenticated = true;
}
}
}
return UPdfEncryption._(
revision: revision,
version: version,
keyLength: keyLength,
streamMethod: streamMethod,
stringMethod: stringMethod,
fileKey: key,
permissionFlags: permissionFlags,
authenticated: authenticated,
ownerAuthenticated: ownerAuthenticated,
encryptMetadata: encryptMetadata,
);
}