Excel & IT Info

아이엑셀러 닷컴, 엑셀러TV

Python

파이썬에서 PDF에 디지털 서명을 추가하는 6가지 방법

권현욱(엑셀러) 2024. 11. 3. 19:31
반응형

들어가기 전에

디지털 서명은 PDF 문서를 보호하는 데 없어서는 안 될 요소가 되었습니다. 디지털 서명은 민감한 정보를 보호하고 서명자의 신원을 확인하는 신뢰할 수 있는 수단을 제공합니다. 파이썬을 사용하여 PDF에 디지털 서명을 추가하는 방법을 소개합니다.

권현욱(엑셀러) | 아이엑셀러 닷컴 대표 · Microsoft Excel MVP · Excel 솔루션 프로바이더 · 작가

이미지: 아이엑셀러 닷컴


※ 이 글은 아래 기사 내용을 토대로 작성되었습니다만, 필자의 개인 의견이나 추가 자료들이 다수 포함되어 있습니다.

  • 원문: 6 Ways of Adding Digital Signatures to PDF in Python
  • URL: https://medium.com/@alice.yang_10652/6-ways-of-adding-digital-signatures-to-pdf-in-python-f9b53949c3e9

PDF에 디지털 서명을 추가하는 파이썬 라이브러리

Python에서 PDF 문서에 디지털 서명을 추가하려면 Python용 Spire.PDF 모듈을 사용합니다. 이 모듈은 PDF 문서의 생성, 읽기, 편집, 변환, 디지털 서명 등 PDF 문서 작업을 위한 포괄적인 기능을 제공합니다. PyPI에서 다음 pip 명령을 사용하여 Python용 Spire.PDF를 설치할 수 있습니다.

pip install Spire.Pdf

 

Python용 Spire.PDF가 이미 설치되어 있고 최신 버전으로 업그레이드하려면 다음 pip 명령을 사용하세요.

pip install --upgrade Spire.Pdf

 

파이썬에서 PDF에 디지털 서명 추가하기

Python용 Spire.PDF에서 PdfOrdinarySignatureMaker 클래스를 사용하면 지정된 인증서 파일을 기반으로 디지털 서명을 만들 수 있습니다. 한편, PdfSignatureAppearance 클래스를 사용하면 서명의 시각적 모양을 사용자 지정할 수 있습니다. 예를 들어, 자필 서명 이미지만 표시하거나 서명자의 이름, 연락처 정보, 위치 및 서명 이유와 같은 추가 세부 정보를 포함하도록 선택할 수 있습니다.

원하는 설정을 구성한 후, 원하는 시각적 모양으로 특정 PDF 페이지에 서명을 추가하려면 PdfOrdinarySignatureMaker 클래스의 MakeSignature 메서드를 호출하면 됩니다. 이 메서드는 다음 매개변수를 허용합니다.

  • sigFieldName(문자열): 서명 필드의 이름
  • 페이지(PdfPageBase): 서명이 그려질 페이지를 나타내는 PdfPageBase 객체
  • x (float): 서명 필드의 x 좌표
  • y (float): 서명 필드의 y 좌표
  • 너비 (float): 서명 필드의 너비
  • 높이 (float): 서명 필드의 높이
  • 서명 모양 (IPdfSignatureAppearance): 사용자 정의된 서명 모양 설정을 보유하는 PdfSignatureAppearance 객체

 

다음은 지정된 시각적 모양을 가진 디지털 서명을 Python에서 PDF 페이지에 추가하는 방법에 대한 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Load the PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")

# Create a signature maker based on a certificate (.pfx) file
signatureMaker = PdfOrdinarySignatureMaker(pdf, "cert.pfx", "password")

# Get the signature object
signature = signatureMaker.Signature
# Set the signature details
signature.Name = "Gary"
signature.ContactInfo = "gary@example.com"
signature.Location = "USA"
signature.Reason = "I Approved"

# Create a signature appearance
appearance = PdfSignatureAppearance(signature)
# Set labels for the signature details
appearance.NameLabel = "Digitally Signed by "
appearance.ContactInfoLabel = "Email: "
appearance.LocationLabel = "Location: "
appearance.ReasonLabel = "Reason: "
# Set the display mode for the signature to include the signature image and additional details
appearance.GraphicMode = GraphicMode.SignImageAndSignDetail
# Set signature image
appearance.SignatureImage = PdfImage.FromFile("signature.png")
# Set the layout for the signature image (none or stretch)
appearance.SignImageLayout = SignImageLayout.none

# Add the signature to a specific location on the second page
signatureMaker.MakeSignature("Signature", pdf.Pages[1], 90.0, 600.0, 200.0, 60.0, appearance)

# Save the signed document
pdf.SaveToFile("Signature.pdf")
pdf.Close()

 

파이썬에서 PDF에 보이지 않는 디지털 서명 추가하기

이전 예제에서는 PDF 페이지에 그래픽 요소로 디지털 서명을 그리는 방법을 보여드렸습니다. 그러나 페이지의 시각적 레이아웃을 변경하고 싶지 않다면 보이지 않는 서명을 대신 추가할 수 있습니다.

보이지 않는 서명은 시각적으로 표시되지 않으므로 프로세스가 더 간단합니다. 사용자 지정 시각적 모양을 정의할 필요 없이 디지털 서명을 만든 다음 PDF 문서에 추가하기만 하면 됩니다.

다음은 Python에서 PDF 문서에 보이지 않는 디지털 서명을 추가하는 방법에 대한 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Load the PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")

# Create a signature maker based on a certificate (.pfx) file
signatureMaker = PdfOrdinarySignatureMaker(pdf, "cert.pfx", "password")

# Add an invisible signature to the document
signatureMaker.MakeSignature("Signature")

# Save the signed document
pdf.SaveToFile("InvisibleSignature.pdf")
pdf.Close()

 

파이썬에서 PDF에 타임스탬프가 있는 디지털 서명 추가하기

타임스탬프는 문서에 서명한 정확한 날짜와 시간을 인증합니다. 이는 문서가 특정 시점에 서명되었다는 검증 가능한 증거로 사용되며, 분쟁이 발생하거나 마감일을 맞출 때 중요할 수 있습니다.

디지털 서명에 타임스탬프를 추가하려면 타임스탬프 서버에 연결해야 합니다. Security_PdfSignature 클래스를 사용하여 디지털 서명을 생성한 다음 이 클래스의 ConfigureTimestamp 메서드를 사용하여 타임스탬프 서버 URL을 구성하면 타임스탬프가 포함된 디지털 서명을 PDF에 추가할 수 있습니다.

다음은 Python에서 PDF에 타임스탬프가 포함된 디지털 서명을 추가하는 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Load the PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")

# Add a digital signature to the second page
signature = Security_PdfSignature(pdf, pdf.Pages[1], "cert.pfx", "password", "Signature")

# Set the bounds of the signature field
signature.Bounds = RectangleF(PointF(90.0, 600.0), SizeF(100.0, 60.0))

# Set the display mode for the signature to display the signature image only
signature.GraphicsMode = Security_GraphicMode.SignImageOnly
# Set the signature image
signature.SignImageSource = PdfImage.FromFile("Signature.png")

# Set document permissions (optional)
# signature.DocumentPermissions = PdfCertificationFlags.AllowFormFill.value | PdfCertificationFlags.ForbidChanges.value

# Configure the timestamp server URL
signature.ConfigureTimestamp("Url of the Timestamp Server")

# Save the signed document
pdf.SaveToFile("TimestampSignature.pdf")
pdf.Close()

 

파이썬에서 PDF에 유효 기호가 있는 디지털 서명 추가하기

일부 구버전(Acrobat 6 이전)에서는 디지털 서명이 문서 내에 직접 유효성 기호(예: 녹색 체크 표시)와 관련 텍스트(“서명 유효”)를 표시하여 서명 모양을 오버레이할 수 있었습니다. 이는 서명의 유효성에 대한 즉각적인 시각적 피드백을 제공하기 때문에 당시에는 일반적인 관행이었습니다. 하지만 이 방식은 더 이상 모범 사례로 간주되지 않으며 일반적으로 PAdES(PDF 고급 전자 서명)와 같은 최신 업계 표준을 준수하지 않는다는 점에 유의해야 합니다.

Python에서 녹색 체크 표시와 같은 유효성 기호가 있는 디지털 서명을 추가하려면 PdfOrdinarySignatureMaker 클래스의 SetAcro6Layers 메서드에 False를 전달하세요.

다음은 Python에서 PDF에 유효성 기호(녹색 체크 표시)가 있는 디지털 서명을 추가하는 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Load the PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")

# Create a digital signature based on a certificate (.pfx) file
signatureMaker = PdfOrdinarySignatureMaker(pdf, "cert.pfx", "password")
# Get the signature object
signature = signatureMaker.Signature

# Create a signature appearance
appearance = PdfSignatureAppearance(signature)
# Set the display mode for the signature to display the signature image only
appearance.GraphicMode = GraphicMode.SignImageOnly
# Set signature image
appearance.SignatureImage = PdfImage.FromFile("Signature.png")
# Set the layout for the signature image (none or stretch)
appearance.SignImageLayout = SignImageLayout.none

# Disable Acro6 layers
signatureMaker.SetAcro6Layers(False)

# Add the signature to a specific location on the second page
signatureMaker.MakeSignature("Signature", pdf.Pages[1], 90.0, 600.0, 250.0, 80.0, appearance)

# Save the signed document
pdf.SaveToFile("SignatureWithGreenTickMark.pdf")
pdf.Close()

 

파이썬에서 PDF의 여러 페이지에 디지털 서명 추가하기

PDF 파일의 여러 페이지에 디지털 서명을 추가하려면 페이지를 반복한 다음 PdfOrdinarySignatureMaker 클래스의 MakeSignature 메서드를 호출하여 각 페이지에 서명을 추가해야 합니다.

다음은 Python에서 PDF 문서의 여러 페이지에 디지털 서명을 추가하는 방법에 대한 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Load the PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")

# Create a signature maker based on a certificate file
signatureMaker = PdfOrdinarySignatureMaker(pdf, "cert.pfx", "password")
# Get the signature object
signature = signatureMaker.Signature

# Create a signature appearance
appearance = PdfSignatureAppearance(signature)
# Set the display mode for the signature
appearance.GraphicMode = GraphicMode.SignImageOnly
# Set signature image
appearance.SignatureImage = PdfImage.FromFile("Signature.png")
# Set the layout for the signature image
appearance.SignImageLayout = SignImageLayout.none

# Iterate through all the pages in the document
for i in range(pdf.Pages.Count):
    page = pdf.Pages[i]
    # Add the signature to a specified location on the current page
    signatureMaker.MakeSignature(f"Signature {i + 1}", page, 90.0, 600.0, 100.0, 60.0, appearance)

# Save the signed document
pdf.SaveToFile("SignMultiPages.pdf")
pdf.Close()

 

파이썬에서 PDF에 여러 디지털 서명 추가하기

PDF에 여러 디지털 서명을 추가하면 여러 당사자가 동일한 문서에 서명할 수 있으므로 모든 참여자가 인증되고 서명 프로세스 내내 문서의 무결성이 유지됩니다.

다음은 Python에서 PDF에 여러 개의 디지털 서명을 추가하는 예제입니다.

from spire.pdf.common import *
from spire.pdf import *

# Add multiple signatures requiring a valid license key, otherwise the signatures will be invalid
# Apply a license key (you can request one by visiting this link: https://www.e-iceblue.com/TemLicense.html)
License.SetLicenseKey("license-key")

def create_and_apply_signature(pdf: PdfDocument, cert_file: str, cert_password: str, image_file: str, page: PdfPageBase, signature_name: str, x: float, y: float, width: float, height: float, output_file: str):
    """
    Creates and applies a digital signature to a specified page in a PDF document.

    Parameters:
    pdf (PdfDocument): The PdfDocument object that represents the PDF document.
    cert_file (str): Path to the certificate file.
    cert_password (str): Password of the certificate file.
    image_file (str): Path to the signature image file.
    page (PdfPageBase): The PdfPageBase object that represents the page where the signature will be applied.
    signature_name (str): Name of the signature field.
    x (float): The X coordinate of the signature field.
    y (float): The Y coordinate of the signature field.
    width (float): The width of the signature field.
    height (float): The height of the signature field.
    output_file (str): Path to save the signed PDF document.
    """
    # Create a signature maker based on the certificate file
    signature_maker = PdfOrdinarySignatureMaker(pdf, cert_file, cert_password)
    
    # Get the signature object
    signature = signature_maker.Signature
    # Create a signature appearance
    appearance = PdfSignatureAppearance(signature)
    # Set the display mode for the signature
    appearance.GraphicMode = GraphicMode.SignImageOnly
    # Set signature image
    appearance.SignatureImage = PdfImage.FromFile(image_file)
    
    # Add the signature
    signature_maker.MakeSignature(signature_name, page, x, y, width, height, appearance)
    
    # Save the signed document (required after each signing)
    pdf.SaveToFile(output_file)

# Example usage
# Load a PDF file
pdf = PdfDocument()
pdf.LoadFromFile("Input.pdf")
pdf.FileInfo.IncrementalUpdate = True

output_file = "MultiSignatures.pdf"
# Add the first signature to the last page of the document
create_and_apply_signature(pdf, "cert1.pfx", "password", "Signature1.png", pdf.Pages[pdf.Pages.Count - 1], "Signature1", 91.0, 641.0, 121.0, 60.0, output_file)

# Load the signed document and add the second signature to the last page of the document
pdf.LoadFromFile(output_file)
create_and_apply_signature(pdf, "cert2.pfx", "password", "Signature2.png", pdf.Pages[pdf.Pages.Count - 1], "Signature2", 213.0, 641.0, 121.0, 60.0, output_file)

pdf.Close()