当前位置:   article > 正文

java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not available

java.security.nosuchalgorithmexception
一、异常情况描述

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

14:04:33.622 [main] ERROR com.test.util.SignUtil - NoSuchAlgorithmException
java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not available
	at 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)
  • 1
  • 2
  • 3
  • 4
  • 5
二、签名方法代码

  以下是做签名的 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);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
三、异常原因分析

  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);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

  运行结果如下所示:

-----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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

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

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

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

-----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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162

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

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

文章参考:
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/560536
推荐阅读
相关标签
  

闽ICP备14008679号