signatureexception是数字签名流程中算法、密钥或数据失配的明确信号;典型表现为验签时signature.verify()因签名长度不符(如rsa签名被截断)、算法不匹配(如sha256withrsa与sha1withrsa混用)、公钥错误或base64解码异常而抛出。

Java 中 SignatureException 不是泛泛的运行时异常,而是数字签名流程中关键环节失败的明确信号。它不反映系统环境或资源问题,而是直接指向签名逻辑本身的不合规——算法、密钥、数据三者之间任一环节失配或损坏,都会触发它。
验签失败是最常见的触发点
调用 signature.verify(signatureBytes) 返回 false 时,通常不会自动抛异常;但若签名字节数组长度与算法预期严重不符(如 RSA 签名长度应等于密钥模长字节数),JDK 底层会主动抛出 SignatureException: Signature length not correct。
- 典型场景:用 2048 位 RSA 私钥签名,生成 256 字节签名;但传输中被截断为 255 字节,验签时立即报此错
- 公钥不匹配也会间接导致长度校验失败——比如用 EC 公钥验 RSA 签名,底层解包失败后回退为长度不合法判断
- 验证前务必确认
signatureBytes.length == (keySizeInBits / 8)(对标准 RSA/PKCS#1)
算法与密钥必须严格一致
签名和验签两端使用的算法名称必须完全相同,且密钥对需真正配对。任何偏差都可能在 verify 阶段表现为 SignatureException。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 签名端用
"SHA256withRSA",验签端误写为"SHA256withECDSA"或"SHA1withRSA",会因 ASN.1 编码结构或哈希输出长度不同而失败 - 使用 Bouncy Castle 提供的算法时,需确保两端 Provider 一致,否则同名算法内部实现可能不同
- 密钥格式要统一:PEM 中的
-----BEGIN RSA PRIVATE KEY-----和-----BEGIN PRIVATE KEY-----(PKCS#8)不可混用,解析错误会导致公钥加载异常,进而引发验签失败
Signature 实例状态管理不当也会连带引发
虽然 IllegalStateException 是更直接的状态异常,但若因误复用实例导致签名过程混乱(如 initVerify 后又调 initSign),后续 verify 调用可能因内部状态错乱而返回 false 或抛出 SignatureException。
- 每个签名/验签操作应使用独立的 Signature 实例,或显式重置:
signature = Signature.getInstance("SHA256withRSA") - 不要在 update 后调用 initVerify —— 这会清空已 update 的数据,且使状态非法,verify 可能因无输入数据而异常
- 验签前检查
signature.getState() == Signature.VERIFY,可提前发现初始化遗漏
传输与编码环节容易被忽视
签名本质是二进制字节流,经 Base64 编码传输后,若解码不完整或含非法字符,还原出的字节数组长度就会出错。
- 接收端用
Base64.getDecoder().decode(signatureBase64)前,先校验字符串是否为合法 Base64(长度 % 4 == 0,仅含 A-Za-z0-9+/=) - 避免手动拼接或截断 Base64 字符串;HTTP Header 中若用自定义字段传签名,注意 URL 编码干扰
- 日志中打印签名长度而非原始内容,便于快速比对:
log.info("Received sig len: {}", signatureBytes.length)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










