SecurityHandlerRev6.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.Security;

namespace DsPdfWeb.Demos
{
    // このサンプルでは、標準セキュリティハンドラのリビジョン6を使用して、
    // 暗号化された PDF を作成する方法を示しています。
    // 
    // PDF 2.0 にて標準セキュリティハンドラとしてリビジョン6が追加されました。
    // 暗号化方式は、「Adobe Supplement to the ISO 32000 BaseVersion: 1.7 ExtensionLevel: 3」に
    // 記載されている標準セキュリティハンドラのリビジョン5と同じAES 256が使用されていますが、
    // 暗号化キーの生成には、より複雑なアルゴリズムが新たに使用されています。
    //
    // 他のセキュリティハンドラの使用例については SecurityHandlers をご参照ください。
    public class SecurityHandlerRev6
    {
        public int CreatePDF(Stream stream)
        {
            // サンプルのパスワード
            const string ownerPassword = "I'm the owner";
            const string userPassword = "I'm a user";

            // Step 1: セキュリティ属性を含むドキュメントを生成します。
            var doc0 = new GcPdfDocument();
            var rc0 = Common.Util.AddNote(
                "標準セキュリティハンドラのリビジョン6の使用方法のデモです。",
                doc0.NewPage());

            // Rev6 のセキュリティハンドラを作成し、セキュリティプロパティを設定します。
            var ssh6 = new StandardSecurityHandlerRev6()
            {
                OwnerPassword = ownerPassword,
                UserPassword = userPassword,
                CopyContent = false,
                PrintingPermissions = PrintingPermissions.Disabled,
                EncryptStrings = true,
            };

            // 作成したハンドラをドキュメントに割り当て、PDF を保存するときに使用されるようにします。
            doc0.Security.EncryptHandler = ssh6;

            // PDF を一時ファイルに保存します。保存したファイルは、次のステップで読み込まれ、検査されます。
            var fn = Path.GetTempFileName();
            doc0.Save(fn);

            // Step 2: 生成された PDF を読み込み、そのセキュリティ属性を検査します。
            var doc = new GcPdfDocument();
            using (var fs = new FileStream(fn, FileMode.Open, FileAccess.Read))
            {
                // パスワードを指定してドキュメントを読み込みます。
                doc.Load(fs, userPassword);

                // この時点で、doc.Security.DecryptHandler が存在する場合はそれを調べることができますが、
                // Security.EncryptHandler が存在しません。
                if (doc.Security.EncryptHandler != null)
                    throw new Exception("この例外は発生しないはずです。");

                var dh = doc.Security.DecryptHandler;
                if (dh is StandardSecurityHandlerRev6 dh_ssh6)
                {
                    // 読み込まれた PDF のセキュリティ属性が Step1 で指定したものであることを確認します。
                    var txt = $"標準セキュリティハンドラのリビジョン6を使用して" +
                        $"生成された PDF に含まれるセキュリティ属性の一部です。\n" +
                        $"- EncryptionAlgorithm: {dh_ssh6.EncryptionAlgorithm}\n" +
                        $"- EncryptionKeyLength: {dh_ssh6.EncryptionKeyLength}\n" +
                        $"- CopyContent: {dh_ssh6.CopyContent}\n" +
                        $"- PrintingPermissions: {dh_ssh6.PrintingPermissions}\n" +
                        $"- EncryptStrings: {dh_ssh6.EncryptStrings}\n" +
                        $"";

                    Common.Util.AddNote(
                        txt,
                        doc.Pages[0],
                        new RectangleF(72, rc0.Bottom + 36, 72 * 6, 72 * 2));

                    // 申し訳ありませんが、これはうまくいきません。
                    var noway = dh_ssh6.OwnerPassword;
                    if (noway != null)
                        throw new Exception("この例外は発生しないはずです。");
                }

                // 新しい PDF を保存します。ただし、この PDF には Security.EncryptHandler を設定していないため、
                // このドキュメントには(Step1 で生成されたものとは異なり)セキュリティがないことに注意してください。
                doc.Save(stream);
            }
            // 一時ファイルを削除します。
            File.Delete(fn);
            // PDF ドキュメントを保存します。
            return doc.Pages.Count;
        }
    }
}