PDF文件签名与盖章



前言

最近看到互联网上越来越多的合同都是以PDF的方式发送合同,并让用户感受到真切的法律效用,PDF合同文件都会有签章。

他有两方面好处,一个是让用户看到合同时有个正式的公司签章;另一个是PDF文件的签名能够防止篡改,具有一定的法律效应。


一、数字签名是什么?

来源:C#数字签名 - micwin - 博客园

数字签名基于哈希算法和公钥加密算法,对明文报文先用哈希算法计算摘要,然后用私钥对摘要进行加密,得到的值就是原文的数字签名。

数字签名(又称公钥数字签名、电子签章)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。

一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。

 二、数字签名的原理

  1. 发件人生成或取得独一无二的加密密码组,包括私钥和公钥。
  2. 发件人书写电子邮件
  3. 发件人用安全的摘要算法获取电子邮件的信息摘要
  4. 发件人再使用私钥对信息摘要进行加密,即可得到数字签名。  
  5. 发件人将数字签名附在信息之后.
  6. 发件人将数字签名和信息(加密或未加密)发送给电子收件人.
  7. 收件人使用发件人的公共密码(公钥)确认发件人的电子签名,即将发件人的数字签名通过公钥进行解密,得到信息摘要
  8. 收件人使用同样安全的摘要算法,获取信息(加密或未加密)的"信息摘要".
  9. 收件人比较两个信息摘要.假如两者相同,则收件人可以确信信息在签发后并未作任何改变
  10. 收件人从证明机构处获得认证证书(或者是通过信息发件人获得),这一证书用以确认发件人发出信息上的数字签名的真实性.证明机构在数字签名系统中是一个典型的受委托管理证明业务的第三方.该证书包含发件人的公共密码和姓名(以及其他可能的附加信息),由证明机构在其上进行数字签名. 


三、PDF的签章


1.引入Nuget包 iTextSharp

代码如下(示例):

Install-Package iTextSharp

iTextSharp开源地址:

itext/itextsharp - GitHub


2.核心代码

代码如下(示例):

        /// <summary>
        /// 为PDF文档签名,并附加公章、附带信息
        /// </summary>
        /// <param name="fileName">PDF源文件</param>
        /// <param name="SignedFileName">签名后的输出文件</param>
        /// <param name="SignerName">签署者</param>
        /// <param name="SignatureImg">公章图片</param>
        /// <param name="Pkcs">证书</param>
        /// <param name="Password">密钥</param>
        /// <param name="SignReason">原因</param>
        /// <param name="SignLocation">位置</param>
        private static void PdfSignWithStamp(string fileName,
                                             string SignedFileName,
                                             string SignerName,
                                             string SignatureImg,
                                             string Pkcs,
                                             string Password,
                                             string SignReason= null,
                                             string SignLocation = null)
        {
            //PKCS概念:.p12是PKCS#12文件的文件扩展名,也称为“PFX文件”的备用扩展,它是保存私钥和证书的组合格式,是最新的签名实用程序使用的格式。
            //一般从规范的证书颁发机构获得有效的认证证书;
            //或者不考虑法律效用等问题,可以直接通过OpenSSL生成PKCS。
            //具体生成方法:搜索“OpenSSL P12”
            var p12 = new Pkcs12Store(new FileStream(Pkcs, FileMode.Open, FileAccess.Read), Password.ToCharArray());
            var alias = "";
            foreach (string al in p12.Aliases)
            {
                if (p12.IsKeyEntry(al) && p12.GetKey(al).Key.IsPrivate)
                {
                    alias = al;   //获得签名中的别名
                    break;
                }
            }
            //获得签名实体
            var pk = p12.GetKey(alias);
            var rsaKey = pk.Key as RsaPrivateCrtKeyParameters;

            //公司盖章的起始位置,在指定时需要设定页码
            int xPos = 450;
            int yPos = 100;  //相对底部
            int width = 100;
            int heith = 100;

            //原始文件
            using (PdfReader reader = new PdfReader(fileName))
            using (FileStream fout = new FileStream(SignedFileName, FileMode.Create, FileAccess.ReadWrite))
            using (PdfStamper stamper = PdfStamper.CreateSignature(reader, fout, '\0', "temp", true))
            {
                //公章图片构造,需要注意的是,默认调试会报错。
                //需要在报错的提示信息下边,选择:调试->异常->CLI的所有复选框均勾掉
                PdfSignatureAppearance appearance = stamper.SignatureAppearance;
                if (!string.IsNullOrEmpty(SignReason))
                    appearance.Reason = SignReason;
                if (!string.IsNullOrEmpty(SignLocation))
                    appearance.Location = SignLocation;
                appearance.SignDate = DateTime.Now;

                //将公章附加到指定页码的具体位置中
                appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(xPos, yPos, xPos + width, yPos + heith), 10, null);
                //公章图片
                appearance.Image = iTextSharp.text.Image.GetInstance(SignatureImg);
                appearance.ImageScale = 0.3f;
                appearance.Image.Alignment = 300;
                appearance.Acro6Layers = true;

                //公章上层附加的文字
                StringBuilder buf = new StringBuilder();
                buf.Append($"Signed:{SignerName}{Environment.NewLine}");
                buf.Append($"Date: {appearance.SignDate.ToString(@"yyyy/MM/dd HH:mm:ss")}");
                appearance.Layer2Text = buf.ToString();

                //签名SHA-256可选SHA-1
                IExternalSignature es = new PrivateKeySignature(rsaKey, "SHA-256");
                var certificat = new Org.BouncyCastle.X509.X509Certificate[] { p12.GetCertificate(alias).Certificate };
                MakeSignature.SignDetached(appearance, es, certificat, null, null, null, 0, CryptoStandard.CMS);
            }
        }
 

3.客户端调用

        static void Main(string[] args)
        {
            string KeyStore = @"doc\pkcs12";
            string Password = "password";
            string Src = @"doc\合同样本(来自网络).pdf";
            string Out = @"doc\合同签名与印章(样例).pdf";
            string Img = @"doc\stamp.jpg";
            string Company = @"company";

            Console.WriteLine("开始PDF签名...");
            //PDF签名,且附加图片
            PdfSignWithStamp(Src, Out, Company, Img, KeyStore,Password);
            Console.WriteLine("签名完成!");
            Console.ReadLine();
        }

4.文档准备

1.干净的PDF源文件:“合同样本(来自网络).pdf”

2.测试用的公章图片:“stamp.jpg”

3.OpenSSL生成的p12证书,可以直接从iTextSharp的源码中拷贝一个。



效果

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Android Studio中进行PDF文件签名的方法有多种。一种常见的方法是使用第三方库来实现签名功能,比如使用iText库。iText是一个功能强大的Java库,可以用于创建和处理PDF文件。你可以在Android Studio中添加iText库的依赖,并使用其提供的API来进行PDF文件签名。 另一种方法是使用Android系统自带的PDF渲染器和绘图功能来实现签名。你可以在Android Studio中使用Canvas和Paint类来绘制签名,然后将绘制的签名保存到PDF文件中。 无论使用哪种方法,你需要先在Android Studio中创建一个界面来显示PDF文件,并提供签名的功能。你可以使用PDF渲染器来加载和显示PDF文件,然后在界面上添加一个绘制区域,用户可以在该区域上进行签名操作。 在用户完成签名后,你可以将签名保存为图片,并将其插入到PDF文件中的指定位置。你可以使用iText库提供的API来实现这一功能,或者使用Android系统的PDF渲染器和绘图功能来实现。 需要注意的是,PDF文件签名涉及到安全性和法律合规性的问题,因此在实际应用中,你可能需要遵循相关的法律法规和安全标准,确保签名的有效性和可靠性。 总结起来,你可以使用第三方库如iText或者使用Android系统自带的PDF渲染器和绘图功能,在Android Studio中实现PDF文件签名的功能。具体的实现方法取决于你的需求和技术要求。 #### 引用[.reference_title] - *1* [如何在Android设备上打印PDF文件](https://blog.csdn.net/weixin_28755331/article/details/117468748)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值