Remove password & restrictions
Strip owner (“admin”) passwords and the print/copy/edit/assemble restrictions that come with them. If the PDF also has a user password, enter it below — otherwise leave the field blank. Powered by the Foxit PDF SDK (PDFDoc::RemoveSecurity()).
How it works
The Foxit PDF SDK calls PDFDoc::RemoveSecurity() on the loaded document, which drops the encryption dictionary and clears the permission bitmask. The PDF is then re-saved with e_SaveFlagNoOriginal | e_SaveFlagXRefStream | e_SaveFlagRemoveRedundantObjects so the output is a fresh, fully-unencrypted file with a compressed xref — not just a re-emission of the original.
If a PDF has only an owner (“admin”) password, the SDK can open it without any password supplied and strip the restrictions directly. If it also has a user password, you have to supply that (or the owner password) so the SDK can decrypt the content. Wrong-password attempts return a 401 instead of guessing.
Pick the machine and the SDK version. The identical source (foxit_remove_security.cpp) is compiled four ways — Kramer (Windows) and Jerry (Linux), each on Foxit PDF SDK 11.0 and 11.1 — a controlled 2×2 for separating SDK-release differences from OS/environment differences. Same code, same input; only the OS or the SDK version changes.
Sample implementation code
The full pipeline this demo runs — load with an optional password, inspect the encryption & permission state, strip the security, then compact-save — in each SDK language binding. Condensed for clarity.
#include "common/fs_common.h"
#include "pdf/fs_pdfdoc.h"
using namespace foxit;
using namespace foxit::common;
using namespace foxit::pdf;
int main() {
Library::Initialize(sn, key);
PDFDoc doc(L"input.pdf");
// Empty string is the no-password case. An owner-password-only PDF
// still loads with "" (GetPasswordType() reports e_PwdNoPassword) and
// its restrictions get stripped below. A user-password PDF returns
// e_ErrPassword -- this demo maps that to exit 5 / HTTP 401.
ErrorCode err = doc.Load(String("password-or-empty"));
if (err == e_ErrPassword) return 5; // password required or wrong
if (err != e_ErrSuccess) return 3;
// --- Inspect the security state before removing it ---
bool was_encrypted = doc.IsEncrypted();
int enc_type = (int)doc.GetEncryptionType(); // password / cert / rms...
int pwd_type = (int)doc.GetPasswordType(); // none / user / owner
uint32 perms = doc.GetUserPermissions();
// Bit SET = action allowed; bit CLEAR = restricted. e.g.:
// 0x0004 print 0x0008 modify 0x0010 extract (copy)
// 0x0100 fill-forms 0x0400 assemble 0x0800 print-high
bool print_blocked = (perms & 0x0004) == 0;
// --- Strip the encryption dictionary + permission bitmask ---
if (!doc.RemoveSecurity()) return 8;
// Compact re-save: rewrite from in-memory state, compressed xref
// stream, unreferenced objects pruned -- a fresh unencrypted file,
// not a re-emission of the original.
doc.SaveAs(L"unlocked.pdf",
PDFDoc::e_SaveFlagNoOriginal
| PDFDoc::e_SaveFlagXRefStream
| PDFDoc::e_SaveFlagRemoveRedundantObjects);
Library::Release();
return 0;
}
using foxit;
using foxit.common;
using foxit.pdf;
Library.Initialize(sn, key);
using var doc = new PDFDoc("input.pdf");
// Empty string is the no-password case. An owner-password-only PDF
// still loads with "" and its restrictions get stripped below. A
// user-password PDF returns e_ErrPassword -> HTTP 401 in this demo.
var err = doc.Load("password-or-empty");
if (err == ErrorCode.e_ErrPassword) return; // password required or wrong
if (err != ErrorCode.e_ErrSuccess) return;
// --- Inspect the security state before removing it ---
bool wasEncrypted = doc.IsEncrypted();
var encType = doc.GetEncryptionType(); // password / cert / rms...
var pwdType = doc.GetPasswordType(); // none / user / owner
uint perms = doc.GetUserPermissions();
// Bit SET = allowed; bit CLEAR = restricted. e.g.:
// 0x0004 print, 0x0008 modify, 0x0010 extract (copy), 0x0400 assemble
bool printBlocked = (perms & 0x0004) == 0;
// --- Strip the encryption dictionary + permission bitmask ---
if (!doc.RemoveSecurity()) return;
// Compact re-save: fresh unencrypted file, compressed xref,
// unreferenced objects pruned.
doc.SaveAs("unlocked.pdf",
(int)(PDFDoc.SaveFlags.e_SaveFlagNoOriginal
| PDFDoc.SaveFlags.e_SaveFlagXRefStream
| PDFDoc.SaveFlags.e_SaveFlagRemoveRedundantObjects));
Library.Release();
import com.foxit.sdk.common.Library;
import com.foxit.sdk.pdf.PDFDoc;
Library.initialize(sn, key);
PDFDoc doc = new PDFDoc("input.pdf");
// Empty string is the no-password case. An owner-password-only PDF
// still loads with "" and its restrictions get stripped below. A
// user-password PDF returns e_ErrPassword -> HTTP 401 in this demo.
int err = doc.load("password-or-empty".getBytes());
if (err == ErrorCode.e_ErrPassword) return; // password required or wrong
if (err != ErrorCode.e_ErrSuccess) return;
// --- Inspect the security state before removing it ---
boolean wasEncrypted = doc.isEncrypted();
int encType = doc.getEncryptionType(); // password / cert / rms...
int pwdType = doc.getPasswordType(); // none / user / owner
long perms = doc.getUserPermissions();
// Bit SET = allowed; bit CLEAR = restricted. e.g.:
// 0x0004 print, 0x0008 modify, 0x0010 extract (copy), 0x0400 assemble
boolean printBlocked = (perms & 0x0004) == 0;
// --- Strip the encryption dictionary + permission bitmask ---
if (!doc.removeSecurity()) return;
// Compact re-save: fresh unencrypted file, compressed xref,
// unreferenced objects pruned.
doc.saveAs("unlocked.pdf",
PDFDoc.e_SaveFlagNoOriginal | PDFDoc.e_SaveFlagXRefStream
| PDFDoc.e_SaveFlagRemoveRedundantObjects);
Library.release();
from FoxitPDFSDKPython3 import *
Library.Initialize(sn, key)
doc = PDFDoc("input.pdf")
# Empty string is the no-password case. An owner-password-only PDF
# still loads with "" and its restrictions get stripped below. A
# user-password PDF returns e_ErrPassword -> HTTP 401 in this demo.
err = doc.Load("password-or-empty")
if err == e_ErrPassword:
raise SystemExit("password required or wrong") # -> 401
assert err == e_ErrSuccess
# --- Inspect the security state before removing it ---
was_encrypted = doc.IsEncrypted()
enc_type = doc.GetEncryptionType() # password / cert / rms...
pwd_type = doc.GetPasswordType() # none / user / owner
perms = doc.GetUserPermissions()
# Bit SET = allowed; bit CLEAR = restricted. e.g.:
# 0x0004 print, 0x0008 modify, 0x0010 extract (copy), 0x0400 assemble
print_blocked = (perms & 0x0004) == 0
# --- Strip the encryption dictionary + permission bitmask ---
assert doc.RemoveSecurity()
# Compact re-save: fresh unencrypted file, compressed xref,
# unreferenced objects pruned.
doc.SaveAs("unlocked.pdf",
PDFDoc.e_SaveFlagNoOriginal | PDFDoc.e_SaveFlagXRefStream
| PDFDoc.e_SaveFlagRemoveRedundantObjects)
Library.Release()
// Foxit PDF SDK for Node.js (naming follows the Node binding conventions)
const { Library, PDFDoc, ErrorCode } = require('@foxitsoftware/foxit-pdf-sdk-node');
Library.initialize(sn, key);
const doc = new PDFDoc('input.pdf');
// Empty string is the no-password case. An owner-password-only PDF
// still loads with '' and its restrictions get stripped below. A
// user-password PDF returns e_ErrPassword -> HTTP 401 in this demo.
const err = doc.load('password-or-empty');
if (err === ErrorCode.e_ErrPassword) throw new Error('password required'); // -> 401
if (err !== ErrorCode.e_ErrSuccess) throw new Error('load failed: ' + err);
// --- Inspect the security state before removing it ---
const wasEncrypted = doc.isEncrypted();
const encType = doc.getEncryptionType(); // password / cert / rms...
const pwdType = doc.getPasswordType(); // none / user / owner
const perms = doc.getUserPermissions();
// Bit SET = allowed; bit CLEAR = restricted. e.g.:
// 0x0004 print, 0x0008 modify, 0x0010 extract (copy), 0x0400 assemble
const printBlocked = (perms & 0x0004) === 0;
// --- Strip the encryption dictionary + permission bitmask ---
if (!doc.removeSecurity()) throw new Error('RemoveSecurity failed');
// Compact re-save: fresh unencrypted file, compressed xref,
// unreferenced objects pruned.
doc.saveAs('unlocked.pdf',
PDFDoc.e_SaveFlagNoOriginal
| PDFDoc.e_SaveFlagXRefStream
| PDFDoc.e_SaveFlagRemoveRedundantObjects);
Library.release();
Samples are condensed for clarity — production code should check every return value and wrap SDK calls in the binding’s exception handling. Exact class/module names can differ slightly between SDK releases; the C++ tab matches the real source this demo runs (kept alongside each binary as foxit_remove_security.cpp in server_11_0/ and server_11_1/).