一、异常情况描述

  笔者在做 RSA 签名时,遇到了一个异常,详见下文。

14:04:33.622 [main] ERROR com.test.util.SignUtil - NoSuchAlgorithmException
java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not availableat java.security.Signature.getInstance(Signature.java:229)at com.test.util.SignUtil.signData(SignUtil.java:29)at com.test.util.SignUtil.main(SignUtil.java:49)
二、签名方法代码

  以下是做签名的 Java 代码。

package com.test.util;import lombok.extern.slf4j.Slf4j;import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;@Slf4j
public class SignUtil {/*** RSA signature 私钥签名** @param data          data to be signed* @param privateKeystr privatekey* @param signMode      签名模式* @return signature result*/public static String signData(String data, String privateKeystr, String signMode) {try {Base64.Decoder decoder = Base64.getDecoder();byte[] keyBytes = decoder.decode(privateKeystr);PKCS8EncodedKeySpec keyspec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(keyspec);Signature signature = Signature.getInstance(signMode);signature.initSign(privateKey);signature.update(data.getBytes(StandardCharsets.UTF_8));byte[] mi = signature.sign();Base64.Encoder encoder = Base64.getEncoder();return encoder.encodeToString(mi);} catch (NoSuchAlgorithmException e) {log.error("NoSuchAlgorithmException", e);} catch (InvalidKeyException e) {log.error("InvalidKeyException", e);} catch (InvalidKeySpecException e) {log.error("InvalidKeySpecException", e);} catch (SignatureException e) {log.error("SignatureException", e);}return null;}public static void main(String[] args) {String data = "sssssaaaaaaa";String signCnt = signData(data,"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","SHA256WithRSAandMGF1");System.out.println(signCnt);}
}
三、异常原因分析

  SHA256WithRSAandMGF1 是 BC Provider 提供的一个签名算法,而 JDK 1.8 的 java.security.* 包中并没有这个 Provider。运行如下代码,可以打印 JDK 中的 Provider 列表,以及所有签名算法。

    public static void main(String[] args) {TreeSet<String> algorithms = new TreeSet<>();Provider[] providers = Security.getProviders();System.out.println("-----Provider 列表如下:-----");for (Provider provider : providers) {System.out.println(provider.getName());}System.out.println("-----支持的签名算法如下:-----");for (Provider provider : providers) {for (Provider.Service service : provider.getServices())if (service.getType().equals("Signature")) {algorithms.add(service.getAlgorithm());}}for (String algorithm : algorithms) {System.out.println(algorithm);}}

  运行结果如下所示:

-----Provider 列表如下:-----
SUN
SunRsaSign
SunEC
SunJSSE
SunJCE
SunJGSS
SunSASL
XMLDSig
SunPCSC
Apple
-----支持的签名算法如下:-----
MD2withRSA
MD5andSHA1withRSA
MD5withRSA
NONEwithDSA
NONEwithECDSA
SHA1withDSA
SHA1withECDSA
SHA1withRSA
SHA224withDSA
SHA224withECDSA
SHA224withRSA
SHA256withDSA
SHA256withECDSA
SHA256withRSA
SHA384withECDSA
SHA384withRSA
SHA512withECDSA
SHA512withRSA

  由结果可见,SHA256WithRSAandMGF1 签名算法确实不支持。

四、解决方法
  Step 1:在项目的 pom.xml 文件中添加如下依赖包,或者以 jar 文件的方式添加到项目中。
     <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.60</version></dependency>
  Step 2:在签名工具类中添加如下静态代码块,将 BouncyCastleProvider 添加到 Provider 列表中。
 static {Security.addProvider(new BouncyCastleProvider());}

  再次运行第三章中的代码,最新输出如下所示。

-----Provider 列表如下:-----
SUN
SunRsaSign
SunEC
SunJSSE
SunJCE
SunJGSS
SunSASL
XMLDSig
SunPCSC
Apple
BC
-----支持的签名算法如下:-----
1.2.840.113549.1.1.10
DDSA
DETDSA
DSA
DSTU4145
ECDDSA
ECDSA
ECGOST3410
ECGOST3410-2012-256
ECGOST3410-2012-512
GOST3410
GOST3411-2012-256WITHECGOST3410-2012-256
GOST3411-2012-512WITHECGOST3410-2012-512
GOST3411WITHDSTU4145
GOST3411WITHDSTU4145LE
GOST3411WITHECGOST3410
MD2WITHRSA
MD2withRSA
MD4WITHRSA
MD5WITHRSA
MD5WITHRSA/ISO9796-2
MD5andSHA1withRSA
MD5withRSA
NONEWITHDSA
NONEwithDSA
NONEwithECDSA
OID.1.2.840.113549.1.1.10
RAWRSASSA-PSS
RIPEMD128WITHRSA
RIPEMD128WITHRSA/X9.31
RIPEMD160WITHECDSA
RIPEMD160WITHPLAIN-ECDSA
RIPEMD160WITHRSA
RIPEMD160WITHRSA/X9.31
RIPEMD160withRSA/ISO9796-2
RIPEMD256WITHRSA
RMD128WITHRSA
RMD128WITHRSA/X9.31
RMD160WITHRSA
RMD160WITHRSA/X9.31
RMD256WITHRSA
RSA
RSASSA-PSS
SHA1WITHCVC-ECDSA
SHA1WITHDDSA
SHA1WITHDETDSA
SHA1WITHECDDSA
SHA1WITHECNR
SHA1WITHPLAIN-ECDSA
SHA1WITHRSA
SHA1WITHRSA/ISO9796-2
SHA1WITHRSA/X9.31
SHA1WITHRSAANDMGF1
SHA1withDSA
SHA1withECDSA
SHA1withRSA
SHA224WITHCVC-ECDSA
SHA224WITHDDSA
SHA224WITHDETDSA
SHA224WITHDSA
SHA224WITHECDDSA
SHA224WITHECDSA
SHA224WITHECNR
SHA224WITHPLAIN-ECDSA
SHA224WITHRSA
SHA224WITHRSA/ISO9796-2
SHA224WITHRSA/X9.31
SHA224WITHRSAANDMGF1
SHA224withDSA
SHA224withECDSA
SHA224withRSA
SHA256WITHCVC-ECDSA
SHA256WITHDDSA
SHA256WITHDETDSA
SHA256WITHDSA
SHA256WITHECDDSA
SHA256WITHECDSA
SHA256WITHECNR
SHA256WITHPLAIN-ECDSA
SHA256WITHRSA
SHA256WITHRSA/ISO9796-2
SHA256WITHRSA/X9.31
SHA256WITHRSAANDMGF1
SHA256withDSA
SHA256withECDSA
SHA256withRSA
SHA3-224WITHDDSA
SHA3-224WITHDSA
SHA3-224WITHECDDSA
SHA3-224WITHECDSA
SHA3-224WITHRSA
SHA3-224WITHRSAANDMGF1
SHA3-256WITHDDSA
SHA3-256WITHDSA
SHA3-256WITHECDDSA
SHA3-256WITHECDSA
SHA3-256WITHRSA
SHA3-256WITHRSAANDMGF1
SHA3-384WITHDDSA
SHA3-384WITHDSA
SHA3-384WITHECDDSA
SHA3-384WITHECDSA
SHA3-384WITHRSA
SHA3-384WITHRSAANDMGF1
SHA3-512WITHDDSA
SHA3-512WITHDSA
SHA3-512WITHECDDSA
SHA3-512WITHECDSA
SHA3-512WITHRSA
SHA3-512WITHRSAANDMGF1
SHA384WITHCVC-ECDSA
SHA384WITHDDSA
SHA384WITHDETDSA
SHA384WITHDSA
SHA384WITHECDDSA
SHA384WITHECDSA
SHA384WITHECNR
SHA384WITHPLAIN-ECDSA
SHA384WITHRSA
SHA384WITHRSA/ISO9796-2
SHA384WITHRSA/X9.31
SHA384WITHRSAANDMGF1
SHA384withECDSA
SHA384withRSA
SHA512(224)WITHRSA
SHA512(224)WITHRSA/ISO9796-2
SHA512(224)WITHRSA/X9.31
SHA512(224)WITHRSAANDMGF1
SHA512(256)WITHRSA
SHA512(256)WITHRSA/ISO9796-2
SHA512(256)WITHRSA/X9.31
SHA512(256)WITHRSAANDMGF1
SHA512WITHCVC-ECDSA
SHA512WITHDDSA
SHA512WITHDETDSA
SHA512WITHDSA
SHA512WITHECDDSA
SHA512WITHECDSA
SHA512WITHECNR
SHA512WITHPLAIN-ECDSA
SHA512WITHRSA
SHA512WITHRSA/ISO9796-2
SHA512WITHRSA/X9.31
SHA512WITHRSAANDMGF1
SHA512withECDSA
SHA512withRSA
SM3WITHSM2
WhirlpoolWITHRSA/ISO9796-2
WhirlpoolWITHRSA/X9.31

  可以看到,BC Provider 已经被添加到列表中,且 SHA256WithRSAandMGF1 算法也在支持的签名算法列表中。

  再次运行签名方法,异常问题已经被修复,能正确对数据进行签名。

文章参考:
  • java.security.NoSuchAlgorithmException: RSA Signature not available

java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not available相关推荐

  1. java.security_Java开发网 - java.security.NoSuchAlgorithmException 问题的一些解决

    Posted by:anray Posted on:2004-12-08 14:32 产出密钥时经常会出现java.security.NoSuchAlgorithmException异常.如下面代码, ...

  2. java.security.NoSuchAlgorithmException: SHA_256 MessageDigest not available

    今天运行代码时出错: java.security.NoSuchAlgorithmException: SHA_256 MessageDigest not available messageDigest ...

  3. java.security.NoSuchAlgorithmException: No such algorithm: RSA/ECB/PKCS1Padding 问题解决

    错误日志:无法找到RSA算法,找不到类,类加载器有限制. 2016-09-28 14:52:39.654 [ERROR] com.csii.mcs.ibs.validator.CSIIPinConve ...

  4. java security_java.security.NoSuchAlgorithmException

    今天遇到一个java的问题: java.security.NoSuchAlgorithmException: EC KeyPairGenerator not available at java.sec ...

  5. Java Security:Java加密框架(JCA)简要说明

    加密服务总是关联到一个特定的算法或类型,它既提供了密码操作(如Digital Signature或MessageDigest),生成或供应所需的加密材料(Key或Parameters)加密操作,也会以 ...

  6. 利用Java自带的MD5加密java.security.MessageDigest;

    MD5加密算法,即"Message-Digest Algorithm 5(信息-摘要算法)",它由MD2.MD3.MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著 ...

  7. Java之加密工具类java.security.MessageDigest或org.apache.commons.codec.digest.DigestUtils

    Java之加密(信息摘要)工具类(依赖:java.security.MessageDigest或org.apache.commons.codec.digest.DigestUtils) 1. java ...

  8. java security / SSL / TLS / md5 / sha / base64 / rsa / des / aes / 3des

    java jdk keytool C:\Program Files\Java\jdk1.7.0_11\bin\keytool.exe [lindows@Loadrunner19 ~]$ ll /opt ...

  9. java rsa sha1_将SHA1和RSA与java.security.Signature和MessageDigest和Cipher结合使用

    我试图了解Java java.security.Signature 类的作用.如果我计算一个SHA1消息摘要,然后使用RSA加密该摘要,则得到的结果与要求 Signature 类对同一事物进行签名的结 ...

  10. Java 类java.security.spec.PKCS8EncodedKeySpec 实例源码

    项目:Alpine    文件:KeyManager.java /*** Saves a key pair.** @param keyPair the key pair to save* @throw ...

最新文章

  1. 英文linux学习app,Linux应用软件,Linux Application Software,音标,读音,翻译,英文例句,英语词典...
  2. windows进程通信 -- WM_COPYDATA消息
  3. Java整数类的compareTo()方法和示例
  4. mysql 用户与权限
  5. 取二维数组最大值_学习Java,你必需要知道这些——Java数组
  6. 第一阶段 高等数学——常量与变量
  7. 现在输入 n 个数字, 以逗号, 分开; 然后可选择升或者 降序排序;
  8. 机械工程师计算机证书考试科目,机械工程师考试科目 内容有哪些
  9. 4. 数据统计分析基础知识
  10. [ECE]模拟试题-2
  11. 红帽linux安装docker,在CentOS7.6、红帽7.6系统中安装Docker:只需3条命令
  12. 9008刷机模式写入超时刷机帮_高通9008刷机大法,避坑指南,救砖前提
  13. 用户注册页面如何测试?
  14. 细粒度情感三元组抽取任务及其最新进展
  15. 骗子收录查询系统源码 附教程
  16. 网站加了外链会在前面自动加上自己网页的网址
  17. Mindjet 一打开鼠标就动不了解决方法
  18. 电话订餐系统讲解(3)
  19. 2021-2025年中国骨髓穿刺针行业市场供需与战略研究报告
  20. python全栈开发工程师招聘_如何当一名优雅的Python全栈开发工程师?

热门文章

  1. 工程项目管理系统源码
  2. 黑马java基础学习笔记第一天
  3. 映美精LoadDeviceStateFromFile问题
  4. 检查pdf字体是否全部嵌入
  5. JavaScript逻辑训练题(二)
  6. ORACLE执行计划中的执行顺序
  7. Netty 解决TCP粘包/半包使用
  8. 基于FPGA的VGA显示,简单的历程和注释(DE2-115)
  9. Android中的Apk的加固(加壳)原理解析和实现
  10. 人工智能入门——机器学习小案例(二)