ExcelEncryptor 2.0.5
See the version list below for details.
dotnet add package ExcelEncryptor --version 2.0.5
NuGet\Install-Package ExcelEncryptor -Version 2.0.5
<PackageReference Include="ExcelEncryptor" Version="2.0.5" />
<PackageVersion Include="ExcelEncryptor" Version="2.0.5" />
<PackageReference Include="ExcelEncryptor" />
paket add ExcelEncryptor --version 2.0.5
#r "nuget: ExcelEncryptor, 2.0.5"
#:package ExcelEncryptor@2.0.5
#addin nuget:?package=ExcelEncryptor&version=2.0.5
#tool nuget:?package=ExcelEncryptor&version=2.0.5
ExcelEncryptor
ExcelEncryptor is a small, focused, free and commercially usable .NET library for applying Excel-compatible Agile Encryption to OOXML workbooks.
Password-protect and decrypt .xlsx / .xlsm files using MS-OFFCRYPTO Agile Encryption.
Tested for compatibility with Apache POI, Microsoft Excel, and LibreOffice Calc.
Works with any library that produces .xlsx bytes: ClosedXML, NPOI, DocumentFormat.OpenXml, or a plain
File.ReadAllBytes.
Commercial use and license
- Commercial use is allowed under
Apache-2.0. - This project is intended to remain free for both personal and commercial use.
- There is no plan to introduce a paid commercial license for this library.
- See
LICENSEand security.md for scope and limitations.
Installation
dotnet add package ExcelEncryptor
Dependencies
- OpenMcdf — Compound File Binary (CFB) read/write
Encryption
From byte array
byte[] xlsxBytes = File.ReadAllBytes("input.xlsx");
ExcelEncryptor.Encrypt.FromBytesToFile(xlsxBytes, "output.xlsx", "password");
From file
ExcelEncryptor.Encrypt.FromFileToFile("input.xlsx", "output.xlsx", "password");
Low-level API (custom algorithm)
var encryptor = new ExcelEncryptor.Encrypt(
keySize: AesKeySize.Aes256,
hashAlgorithm: HashAlgorithmType.Sha512
);
encryptor.EncryptFile("input.xlsx", "output.xlsx", "password");
Supported key sizes: Aes128 (default), Aes192, Aes256
Supported hash algorithms: Sha1 (default), Sha256, Sha384, Sha512, Md5 (legacy compatibility only)
Recommended and legacy settings
- Recommended for new files:
Aes256+Sha512 - Legacy compatibility:
Sha1andMd5are kept for compatibility with older environments - Security note:
Md5is not recommended for new encryption
Decryption
// Decrypt to byte array
byte[] xlsxBytes = ExcelEncryptor.Encrypt.Decrypt("encrypted.xlsx", "password");
// Decrypt to file
ExcelEncryptor.Encrypt.DecryptToFile("encrypted.xlsx", "decrypted.xlsx", "password");
For ClosedXML users
No helper class needed. Save the workbook to a MemoryStream and pass the bytes directly.
var wb = new XLWorkbook();
wb.AddWorksheet("Sheet1").Cell("A1").Value = "Hello";
using var ms = new MemoryStream();
wb.SaveAs(ms);
ExcelEncryptor.Encrypt.FromBytesToFile(ms.ToArray(), "output.xlsx", "password");
For NPOI users
The library itself has no dependency on NPOI. If you use NPOI, the following helper stream lets you pipe
IWorkbook.Write() output directly into encryption without a temporary file.
Copy this class into your project:
using System.IO;
/// <summary>
/// Drop-in stream for NPOI's IWorkbook.Write() that encrypts on Close().
/// Copy into your project — not part of the ExcelEncryptor package itself.
/// </summary>
public class NpoiXlsxPasswordFileOutputStream : Stream
{
private readonly MemoryStream _buffer = new();
private readonly string _outputPath;
private readonly string _password;
public NpoiXlsxPasswordFileOutputStream(string outputPath, string password)
{
_outputPath = outputPath;
_password = password;
}
public override bool CanRead => false;
public override bool CanSeek => true;
public override bool CanWrite => true;
public override long Length => _buffer.Length;
public override long Position
{
get => _buffer.Position;
set => _buffer.Position = value;
}
public override void Write(byte[] buffer, int offset, int count)
=> _buffer.Write(buffer, offset, count);
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count) => 0;
public override long Seek(long offset, SeekOrigin origin)
=> _buffer.Seek(offset, origin);
public override void SetLength(long value)
=> _buffer.SetLength(value);
public override void Close()
{
base.Close();
ExcelEncryptor.Encrypt.FromBytesToFile(_buffer.ToArray(), _outputPath, _password);
}
}
Usage:
IWorkbook wb = new XSSFWorkbook();
wb.CreateSheet("Sheet1").CreateRow(0).CreateCell(0).SetCellValue("Hello");
using var stream = new NpoiXlsxPasswordFileOutputStream("output.xlsx", "password");
wb.Write(stream);
Compatibility
ExcelEncryptor is tested with:
- Manual open checks with Microsoft Excel for Mac
- Manual open checks with Microsoft Excel for Windows
- Manual open checks with LibreOffice Calc on Ubuntu via Docker/VNC
- Automated Apache POI interoperability tests
- Automated tests for
.xlsxfiles containing formulas, styles, Japanese sheet names, and embedded images
For details, see compatibility.md.
Changelog
v2.0.5
- Added automated compatibility tests
- Added Apache POI interoperability tests
- Added image-containing workbook tests
- Added manual verification artifacts for Excel / LibreOffice checks
For details, see tests.
v2.0.0
- Library is now NPOI-free — depends only on OpenMcdf
NpoiXlsxPasswordFileOutputStreamremoved from package; available as a copy-paste snippet above- Full backward compatibility on the encryption/decryption API
v1.5.0
- Removed OpenMcdf dependency (reverted in v2.0.0)
v1.0.0
- Initial release
License
Apache-2.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| .NET Framework | net47 is compatible. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.