Rsa2验签报错【java.security.SignatureException: Signature length not correct】的解决办法

本文详细解析了在使用RSA算法进行数字签名验证时遇到的签名长度不正确的异常问题。问题出现在将签名字符串转换为字节数据的过程中,由于使用了不一致的数据处理方式,导致签名长度与预期不符。文章提供了具体的代码示例,并给出了正确的解决方案,即在获取签名字符串字节数组时,应采用与签名时相同的方法,使用Base64解码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

在进行RSA2进行验签的时候,报了以下错误:

java.security.SignatureException: Signature length not correct: got 344 but was expecting 256
at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:189)
at java.security.Signature$Delegate.engineVerify(Signature.java:1192)
at java.security.Signature.verify(Signature.java:626)

 

翻译成中文的意思是:java.security.signatureException:签名长度不正确:得到344,但期望256

 

问题原因是:

  在生成签名的时候,用的是 Base64.encodeBase64String(signByte) 成签名字符串。

 1     /**
 2      * 生成签名字符串.
 3      * @param encryptStr
 4      * @return
 5      * @throws Exception
 6      */
 7     private static String generateSignByRsa(String encryptStr) throws Exception {
 8         if (logger.isInfoEnabled()) {
 9             logger.info("生成Rsa签名字符串...");
10         }
11 
12         // 用商户私钥生成签名字符串
13         RsaEncrypt rsaEncrypt = new RsaEncrypt();
14         rsaEncrypt.loadPrivateKey(MpayConfig.signMap.get(MpayConfig.PRIVATE_KEY));
15         byte[] signByte = rsaEncrypt.sign(encryptStr, rsaEncrypt.getPrivateKey());
16         String reqSign = Base64.encodeBase64String(signByte);
17         logger.info("Rsa签名字符串:" + reqSign);
18         return reqSign;
19     }

 

  在验签的时候,直接getBytes方法返回字节数据,这样就导致签名字符串长度不一致了。

1   RsaEncrypt rsaEncrypt=new RsaEncrypt();
2   rsaEncrypt.loadPublicKey(publicKey);
3   return rsaEncrypt.verifySign(content,sign.getBytes(RsaEncrypt.ENCODING),rsaEncrypt.getPublicKey());

 

解决方案:

  正确的方式应该是,获取签名字符串字节数组时,跟签名时保持一样,用Base64Util.decode(sign)方法来获取

1     RsaEncrypt rsaEncrypt=new RsaEncrypt();
2     rsaEncrypt.loadPublicKey(publicKey);
3     byte[] signByte = Base64Util.decode(sign);
4     return rsaEncrypt.verifySign(content,signByte,rsaEncrypt.getPublicKey());

 

转载于:https://www.cnblogs.com/caoweixiong/p/10782434.html

<think>好的,用户遇到了Java中的NoSuchAlgorithmException异常,具体是RSA Signature不可用。我需要先理解这个问题的原因,然后给出解决方案。 首先,根据引用[2],这个异常通常是因为Java加密架构中没有所需的算法。可能的原因有几个:算法名称拼写错误、未安装对应的提供者,或者环境配置问题。我需要逐一分析这些可能性。 第一步,检查算法名称是否正确。用户使用的是"RSA",但正确的名算法可能需要更具体的格式,比如"SHA256withRSA"。需要建议用户确认算法名称是否正确。 第二步,确认加密提供者是否安装。Java默认的提供者可能没有包含所需的RSA实现,用户可能需要手动添加Bouncy Castle等第三方提供者。引用[3]中提到通过复制jar包到指定目录来解决类似问题,这可能涉及到类路径的问题。需要指导用户如何添加提供者,比如使用Security.addProvider()或者在java.security配置文件中注册。 第三步,检查JRE环境是否完整。如果用户使用的是自定义的JRE,可能缺少必要的加密模块。建议用户检查jre/lib/security目录下的配置文件,或者使用完整的JRE版本。 另外,引用[3]的解决方案提到将扩展jar包移动到lib目录,这可能是因为类加载器无法正确加载这些库。需要提醒用户确保相关jar包在类路径中,并且权限设置正确。 最后,可能需要考虑代码中的异常处理,比如使用try-catch块并提供备用算法,或者提示用户安装无限强度策略文件,特别是在使用长密钥时。 总结下来,解决方案应包括检查算法名称、添加加密提供者、证JRE完整性、检查类路径配置以及更新策略文件。需要分步骤详细说明,确保用户能一步步排查问题。</think>### JavaRSA名算法不可用的解决方案 当出现`java.security.NoSuchAlgorithmException: RSA Signature not available`异常时,通常是由于Java加密体系结构中缺少对应算法的实现或配置错误导致。以下是逐步排查和解决的方案: --- #### **1. 检查算法名称拼写** 确保代码中使用的算法名称符合Java标准命名规范。 - **错误示例**:`Signature.getInstance("RSA")` - **正确示例**:`Signature.getInstance("SHA256withRSA")` - RSA名需结合哈希算法,如`SHA256withRSA`、`SHA1withRSA`等[^2]。 --- #### **2. 添加加密服务提供者** Java默认的`SunJCE`提供者可能未包含特定实现,需手动添加第三方库(如Bouncy Castle): ```java // 在代码中动态添加Bouncy Castle提供者 Security.addProvider(new BouncyCastleProvider()); Signature signature = Signature.getInstance("SHA256withRSA", "BC"); ``` - **依赖配置**:需将`bcprov-jdk15on-xxx.jar`添加到类路径[^3]。 --- #### **3. 证JRE环境完整性** 若使用自定义JRE(如通过jlink生成),需确保包含`java.base`模块中的加密组件: - 检查`jre/lib/security/java.security`文件,确认包含以下行: ```properties security.provider.1=SUN security.provider.2=SunRsaSign ``` --- #### **4. 检查类路径配置** 确保相关JAR包(如Bouncy Castle)位于以下位置之一: - 项目依赖目录(如`lib/`) - JRE扩展目录(如`jre/lib/ext/`)[^3] --- #### **5. 更新策略文件(可选)** 若涉及高强度加密(如256位AES),需安装Java无限制强度策略文件: 1. 从Oracle官网下载`local_policy.jar`和`US_export_policy.jar`。 2. 替换`jre/lib/security`目录下的同名文件。 --- #### **6. 代码示例** ```java public static void main(String[] args) { try { // 添加Bouncy Castle提供者 Security.addProvider(new BouncyCastleProvider()); Signature signature = Signature.getInstance("SHA256withRSA", "BC"); // 初始化密钥对等操作... } catch (NoSuchAlgorithmException | NoSuchProviderException e) { e.printStackTrace(); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值