签章电子验签

582

数字签名电子签章验签

1.依赖jar包
<dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.pdf.free</artifactId>
            <version>2.2.2</version>
</dependency>

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.1</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.49</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.49</version>
            <type>jar</type>
</dependency>
2.验证逻辑
    @PostMapping("verify")
    @ResponseBody
    public RespMsg verify(MultipartFile file) throws IOException
    {
        InputStream inputStream = null;

        BouncyCastleProvider bcp = new BouncyCastleProvider();
        Security.insertProviderAt(bcp, 1);

        try
        {
            if (file == null||file.getSize()==0)
            {
                return new RespMsg().badReq().msg("上传文件不可为空");
            }

            inputStream = file.getInputStream();

            PdfReader pdfReader = new PdfReader(file.getBytes());
            //获取签章信息
            AcroFields acroFields = pdfReader.getAcroFields();

            HashMap<String, Object> data = new HashMap<>();
            //原始文件名
            String originalName = file.getOriginalFilename();
            //获取文件md5(文件摘要值)
            String md5 = SecureUtil.md5(inputStream);
            //获取文件格式
            String type = originalName.substring(originalName.lastIndexOf(".")).toLowerCase();

            if(!type.equals(".pdf"))
            {
                return new RespMsg().badReq().msg("请上传pdf文件");
            }

            data.put("fileName", originalName);
            data.put("md5", md5);

            //获取文档对象
            PdfDocument doc = new PdfDocument();
            doc.loadFromBytes(file.getBytes());
            //获取域集合
            PdfFormWidget pdfFormWidget = (PdfFormWidget) doc.getForm();
            PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.getFieldsWidget();

            List<HashMap<String, Object>> sign = new ArrayList<>();

            //遍历域
            for (int i = 0; i < pdfFormFieldWidgetCollection.getCount(); i++)
            {
                HashMap<String, Object> signItem = new HashMap<>();
                //判定是否为签名域
                if (pdfFormFieldWidgetCollection.get(i) instanceof PdfSignatureFieldWidget)
                {
                    //获取签名域
                    PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget) pdfFormFieldWidgetCollection.get(i);
                    //获取签名
                    PdfSignature signature = signatureFieldWidget.getSignature();
                    //判定签名是否有效
                    boolean result = acroFields.verifySignature(signature.getSignatureName()).verify();
//                    boolean result = signature.verifySignature();
                    if (result)
                    {
                        signItem.put("ispass", true);
                    }else
                    {
                        signItem.put("ispass", false);
                    }
                    try
                    {
                        //证书颁发机构
                        String signCompany = signature.getCertificate().getIssuer();
                        signItem.put("signCompany", signCompany);
                        //获取subject
                        String subject = signature.getCertificate().getSubject();
                        //获取签约时间
                        String signDate = DateUtil.format(signature.getDate(), "yyyy/MM/dd HH:mm:ss");
                        signItem.put("signDate", signDate);
                        //获取签署人名
                        String signName = ReUtil.get("CN=[\\u4e00-\\u9fa5]*", subject, 0).replace("CN=", "");
                        signItem.put("signName", signName);

                        String certificate = signature.getCertificate().toString();
                        //获取截取方位
                        int startTimeIndex = certificate.indexOf("[Not Before]") + 12;
                        int endTimeIndex = certificate.indexOf("[Not After]");
                        int endTimeLastIndex = certificate.indexOf("[Not After]") + 11;
                        int thumbprintIndex = certificate.indexOf("[Thumbprint]");
                        //获取有效期开始时间
                        String startTime = signature.getCertificate().toString().substring(startTimeIndex, endTimeIndex).trim();
                        signItem.put("startTime", startTime);
                        //获取有效期结束时间
                        String endTime = signature.getCertificate().toString().substring(endTimeLastIndex, thumbprintIndex).trim();
                        signItem.put("endTime", endTime);

                        sign.add(signItem);
                    }
                    catch (Exception e)
                    {
                        logger.info("验签失败:/api/signature/verify:{}", e.getMessage());
                    }

                }
            }
            data.put("sign", sign);

            return new RespMsg().success().msg("请求成功!").data(data);
        }
        catch (Exception e)
        {
            logger.info("验签失败:/api/signature/verify:{}", e.getMessage());
            return new RespMsg().fail().msg("服务器发生错误请重试!");
        }
        finally
        {
            if (inputStream != null)
            {
                inputStream.close();
            }
        }
    }