diff --git a/internal/certificate/service.go b/internal/certificate/service.go
index 406e183c..a207d1c3 100644
--- a/internal/certificate/service.go
+++ b/internal/certificate/service.go
@@ -5,7 +5,7 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"errors"
+	"fmt"
 	"strconv"
 	"strings"
 	"time"
@@ -59,7 +59,7 @@ func (s *CertificateService) InitSchedule(ctx context.Context) error {
 	return nil
 }
 
-func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.CertificateArchiveFileReq) ([]byte, error) {
+func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.CertificateArchiveFileReq) (*dtos.CertificateArchiveFileResp, error) {
 	certificate, err := s.certRepo.GetById(ctx, req.CertificateId)
 	if err != nil {
 		return nil, err
@@ -69,6 +69,10 @@ func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.Certific
 	zipWriter := zip.NewWriter(&buf)
 	defer zipWriter.Close()
 
+	resp := &dtos.CertificateArchiveFileResp{
+		FileFormat: "zip",
+	}
+
 	switch strings.ToUpper(req.Format) {
 	case "", "PEM":
 		{
@@ -97,7 +101,8 @@ func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.Certific
 				return nil, err
 			}
 
-			return buf.Bytes(), nil
+			resp.FileBytes = buf.Bytes()
+			return resp, nil
 		}
 
 	case "PFX":
@@ -134,7 +139,8 @@ func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.Certific
 				return nil, err
 			}
 
-			return buf.Bytes(), nil
+			resp.FileBytes = buf.Bytes()
+			return resp, nil
 		}
 
 	case "JKS":
@@ -171,7 +177,8 @@ func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.Certific
 				return nil, err
 			}
 
-			return buf.Bytes(), nil
+			resp.FileBytes = buf.Bytes()
+			return resp, nil
 		}
 
 	default:
@@ -180,25 +187,30 @@ func (s *CertificateService) ArchiveFile(ctx context.Context, req *dtos.Certific
 }
 
 func (s *CertificateService) ValidateCertificate(ctx context.Context, req *dtos.CertificateValidateCertificateReq) (*dtos.CertificateValidateCertificateResp, error) {
-	info, err := certs.ParseCertificateFromPEM(req.Certificate)
+	certX509, err := certs.ParseCertificateFromPEM(req.Certificate)
+	if err != nil {
+		return nil, err
+	} else if time.Now().After(certX509.NotAfter) {
+		return nil, fmt.Errorf("certificate has expired at %s", certX509.NotAfter.UTC().Format(time.RFC3339))
+	}
+
+	return &dtos.CertificateValidateCertificateResp{
+		IsValid: true,
+		Domains: strings.Join(certX509.DNSNames, ";"),
+	}, nil
+}
+
+func (s *CertificateService) ValidatePrivateKey(ctx context.Context, req *dtos.CertificateValidatePrivateKeyReq) (*dtos.CertificateValidatePrivateKeyResp, error) {
+	_, err := certcrypto.ParsePEMPrivateKey([]byte(req.PrivateKey))
 	if err != nil {
 		return nil, err
 	}
 
-	if time.Now().After(info.NotAfter) {
-		return nil, errors.New("证书已过期")
-	}
-
-	return &dtos.CertificateValidateCertificateResp{
-		Domains: strings.Join(info.DNSNames, ";"),
+	return &dtos.CertificateValidatePrivateKeyResp{
+		IsValid: true,
 	}, nil
 }
 
-func (s *CertificateService) ValidatePrivateKey(ctx context.Context, req *dtos.CertificateValidatePrivateKeyReq) error {
-	_, err := certcrypto.ParsePEMPrivateKey([]byte(req.PrivateKey))
-	return err
-}
-
 func buildExpireSoonNotification(certificates []*domain.Certificate) *struct {
 	Subject string
 	Message string
diff --git a/internal/domain/dtos/certificate.go b/internal/domain/dtos/certificate.go
index cf9eb785..a1853df0 100644
--- a/internal/domain/dtos/certificate.go
+++ b/internal/domain/dtos/certificate.go
@@ -5,22 +5,24 @@ type CertificateArchiveFileReq struct {
 	Format        string `json:"format"`
 }
 
+type CertificateArchiveFileResp struct {
+	FileBytes  []byte `json:"fileBytes"`
+	FileFormat string `json:"fileFormat"`
+}
+
 type CertificateValidateCertificateReq struct {
 	Certificate string `json:"certificate"`
 }
 
 type CertificateValidateCertificateResp struct {
-	Domains string `json:"domains"`
+	IsValid bool   `json:"isValid"`
+	Domains string `json:"domains,omitempty"`
 }
 
 type CertificateValidatePrivateKeyReq struct {
 	PrivateKey string `json:"privateKey"`
 }
 
-type CertificateUploadReq struct {
-	WorkflowId     string `json:"workflowId"`
-	WorkflowNodeId string `json:"workflowNodeId"`
-	CertificateId  string `json:"certificateId"`
-	Certificate    string `json:"certificate"`
-	PrivateKey     string `json:"privateKey"`
+type CertificateValidatePrivateKeyResp struct {
+	IsValid bool `json:"isValid"`
 }
diff --git a/internal/rest/handlers/certificate.go b/internal/rest/handlers/certificate.go
index ded0db94..01b2b06d 100644
--- a/internal/rest/handlers/certificate.go
+++ b/internal/rest/handlers/certificate.go
@@ -11,9 +11,9 @@ import (
 )
 
 type certificateService interface {
-	ArchiveFile(ctx context.Context, req *dtos.CertificateArchiveFileReq) ([]byte, error)
+	ArchiveFile(ctx context.Context, req *dtos.CertificateArchiveFileReq) (*dtos.CertificateArchiveFileResp, error)
 	ValidateCertificate(ctx context.Context, req *dtos.CertificateValidateCertificateReq) (*dtos.CertificateValidateCertificateResp, error)
-	ValidatePrivateKey(ctx context.Context, req *dtos.CertificateValidatePrivateKeyReq) error
+	ValidatePrivateKey(ctx context.Context, req *dtos.CertificateValidatePrivateKeyReq) (*dtos.CertificateValidatePrivateKeyResp, error)
 }
 
 type CertificateHandler struct {
@@ -38,10 +38,10 @@ func (handler *CertificateHandler) archiveFile(e *core.RequestEvent) error {
 		return resp.Err(e, err)
 	}
 
-	if bt, err := handler.service.ArchiveFile(e.Request.Context(), req); err != nil {
+	if res, err := handler.service.ArchiveFile(e.Request.Context(), req); err != nil {
 		return resp.Err(e, err)
 	} else {
-		return resp.Ok(e, bt)
+		return resp.Ok(e, res)
 	}
 }
 
@@ -51,10 +51,10 @@ func (handler *CertificateHandler) validateCertificate(e *core.RequestEvent) err
 		return resp.Err(e, err)
 	}
 
-	if rs, err := handler.service.ValidateCertificate(e.Request.Context(), req); err != nil {
+	if res, err := handler.service.ValidateCertificate(e.Request.Context(), req); err != nil {
 		return resp.Err(e, err)
 	} else {
-		return resp.Ok(e, rs)
+		return resp.Ok(e, res)
 	}
 }
 
@@ -64,9 +64,9 @@ func (handler *CertificateHandler) validatePrivateKey(e *core.RequestEvent) erro
 		return resp.Err(e, err)
 	}
 
-	if err := handler.service.ValidatePrivateKey(e.Request.Context(), req); err != nil {
+	if res, err := handler.service.ValidatePrivateKey(e.Request.Context(), req); err != nil {
 		return resp.Err(e, err)
 	} else {
-		return resp.Ok(e, nil)
+		return resp.Ok(e, res)
 	}
 }
diff --git a/ui/src/api/certificates.ts b/ui/src/api/certificates.ts
index 3c00fdcf..6a8935bb 100644
--- a/ui/src/api/certificates.ts
+++ b/ui/src/api/certificates.ts
@@ -3,10 +3,14 @@ import { ClientResponseError } from "pocketbase";
 import { type CertificateFormatType } from "@/domain/certificate";
 import { getPocketBase } from "@/repository/_pocketbase";
 
+type ArchiveRespData = {
+  fileBytes: string;
+};
+
 export const archive = async (certificateId: string, format?: CertificateFormatType) => {
   const pb = getPocketBase();
 
-  const resp = await pb.send<BaseResponse<string>>(`/api/certificates/${encodeURIComponent(certificateId)}/archive`, {
+  const resp = await pb.send<BaseResponse<ArchiveRespData>>(`/api/certificates/${encodeURIComponent(certificateId)}/archive`, {
     method: "POST",
     headers: {
       "Content-Type": "application/json",
@@ -24,6 +28,7 @@ export const archive = async (certificateId: string, format?: CertificateFormatT
 };
 
 type ValidateCertificateResp = {
+  isValid: boolean;
   domains: string;
 };
 
@@ -46,9 +51,13 @@ export const validateCertificate = async (certificate: string) => {
   return resp;
 };
 
+type ValidatePrivateKeyResp = {
+  isValid: boolean;
+};
+
 export const validatePrivateKey = async (privateKey: string) => {
   const pb = getPocketBase();
-  const resp = await pb.send<BaseResponse>(`/api/certificates/validate/private-key`, {
+  const resp = await pb.send<BaseResponse<ValidatePrivateKeyResp>>(`/api/certificates/validate/private-key`, {
     method: "POST",
     headers: {
       "Content-Type": "application/json",
diff --git a/ui/src/components/certificate/CertificateDetail.tsx b/ui/src/components/certificate/CertificateDetail.tsx
index d57a9609..6c842a36 100644
--- a/ui/src/components/certificate/CertificateDetail.tsx
+++ b/ui/src/components/certificate/CertificateDetail.tsx
@@ -22,7 +22,7 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
   const handleDownloadClick = async (format: CertificateFormatType) => {
     try {
       const res = await archiveCertificate(data.id, format);
-      const bstr = atob(res.data);
+      const bstr = atob(res.data.fileBytes);
       const u8arr = Uint8Array.from(bstr, (ch) => ch.charCodeAt(0));
       const blob = new Blob([u8arr], { type: "application/zip" });
       saveAs(blob, `${data.id}-${data.subjectAltNames}.zip`);