在Spring Boot中实现PDF文件的加密传输并在浏览器解密显示,可以按照以下步骤进行:
后端实现(Spring Boot)
添加依赖:确保项目中包含Web相关依赖。
org.springframework.boot spring-boot-starter-web PDF读取与加密:创建Controller处理文件加密。
import org.springframework.core.io.ClassPathResource; import org.springframework.http.ResponseEntity; import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import java.security.SecureRandom; import java.util.Base64; import java.util.HashMap; import java.util.Map;
@RestController public class PdfController {
@GetMapping("/encrypted-pdf")
public ResponseEntity<Map<String, String>> getEncryptedPdf() throws Exception {
// 读取PDF文件
ClassPathResource resource = new ClassPathResource("static/sample.pdf");
byte[] fileContent = StreamUtils.copyToByteArray(resource.getInputStream());
// 生成AES密钥和IV
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
byte[] keyBytes = secretKey.getEncoded();
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
// 加密文件内容
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
byte[] encryptedContent = cipher.doFinal(fileContent);
// Base64编码响应数据
Map<String, String> response = new HashMap<>();
response.put("encryptedData", Base64.getEncoder().encodeToString(encryptedContent));
response.put("key", Base64.getEncoder().encodeToString(keyBytes));
response.put("iv", Base64.getEncoder().encodeToString(iv));
return ResponseEntity.ok(response);
}
}
前端实现(JavaScript)
获取加密数据并解密:使用Fetch API和CryptoJS解密。
PDF解密显示<script>
fetch('/encrypted-pdf')
.then(response => response.json())
.then(data => {
// 解析Base64数据
const encryptedData = CryptoJS.enc.Base64.parse(data.encryptedData);
const key = CryptoJS.enc.Base64.parse(data.key);
const iv = CryptoJS.enc.Base64.parse(data.iv);
// 使用AES-CBC解密
const decrypted = CryptoJS.AES.decrypt(
{ ciphertext: encryptedData },
key,
{ iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }
);
// 转换为二进制字符串
const binaryString = decrypted.toString(CryptoJS.enc.Latin1);
// 生成Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 创建Blob并显示PDF
const blob = new Blob([bytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const embed = document.createElement('embed');
embed.src = url;
embed.type = 'application/pdf';
embed.width = '100%';
embed.height = '600px';
document.getElementById('pdfViewer').appendChild(embed);
})
.catch(error => console.error('Error:', error));
</script>
注意事项
密钥传输安全:示例中密钥通过HTTP传输,实际应用应使用HTTPS以确保安全。 错误处理:添加适当的异常处理和用户提示。 CORS配置:若前后端分离,需在Spring Boot中配置CORS。 文件大小:大文件需分块处理,避免内存溢出。 加密参数一致性:确保前后端的算法、模式和填充方式一致。
测试流程
将PDF文件放置在 src/main/resources/static/ 目录下。 启动Spring Boot应用。 访问前端页面,应显示解密后的PDF文件。
此方案通过AES-CBC加密保护PDF文件,确保传输安全,并利用浏览器能力实现无缝解密与展示。