diff --git a/src/main/java/com/yexuejc/base/encrypt/RSA.java b/src/main/java/com/yexuejc/base/encrypt/RSA.java index 5d1f6e5..fd789cd 100644 --- a/src/main/java/com/yexuejc/base/encrypt/RSA.java +++ b/src/main/java/com/yexuejc/base/encrypt/RSA.java @@ -93,7 +93,7 @@ public class RSA { *
AES的(算法/模式/填充)组合 参照 {@link AES.ALGORITHM}
+ *AES的(算法/模式/填充)组合 参照 {@link ALGORITHM}
*/ public String transformation = "RSA"; /** @@ -127,6 +127,42 @@ public class RSA { */ public final SignAlgorithm signAlgorithm = SignAlgorithm.SHA256withRSA; + /** + * 加密模式 + */ + // @formatter:off + public enum ALGORITHM { + // 模式 填充 说明 + // RSA/ECB/PKCS1Padding PKCS#1 v1.5 传统填充方式,兼容性好,但可能存在安全风险(如选择密文攻击)。 + RSA_ECB_PKCS1Padding("RSA/ECB/PKCS1Padding"), + // RSA/ECB/OAEPWithSHA-1AndMGF1Padding OAEP (SHA-1) 比 PKCS1Padding 更安全,但 SHA-1 已不推荐。 + RSA_ECB_SHA_1("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"), + // RSA/ECB/OAEPWithSHA-224AndMGF1Padding OAEP (SHA-224) 比 PKCS1Padding 更安全,但 SHA-224 已不推荐。 + RSA_ECB_SHA_224("RSA/ECB/OAEPWithSHA-224AndMGF1Padding"), + // RSA/ECB/OAEPWithSHA-256AndMGF1Padding OAEP (SHA-256) 推荐,安全性更高。 + RSA_ECB_SHA_256("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"), + // RSA/ECB/OAEPWithSHA-384AndMGF1Padding OAEP (SHA-384) 更高安全性,但性能稍差。 + RSA_ECB_SHA_384("RSA/ECB/OAEPWithSHA-384AndMGF1Padding"), + // RSA/ECB/OAEPWithSHA-512AndMGF1Padding OAEP (SHA-512) 最高安全性,但计算开销大。 + RSA_ECB_SHA_512("RSA/ECB/OAEPWithSHA-512AndMGF1Padding"), + // RSA/ECB/OAEPWithSHA3-256AndMGF1Padding OAEP (SHA3-256) 2021 年新增,与 SHA-256 相同,但性能更高,Bouncy Castle 支持 + RSA_ECB_SHA3_256("RSA/ECB/OAEPWithSHA3-256AndMGF1Padding"), + // RSA/None/NoPadding 无 仅用于特殊场景,Bouncy Castle 支持 + RSA_None_NoPadding("RSA/None/NoPadding"), + // RSA/None/PKCS1Padding PKCS#1 v1.5 Bouncy Castle 支持 + RSA_None_PKCS1Padding("RSA/None/PKCS1Padding"), + // RSA/None/OAEPPadding OAEP (SHA-1) Bouncy Castle 支持 + RSA_None_OAEPPadding("RSA/None/OAEPPadding"), + // RSA/None/ISO9796-1Padding ISO9796-1 旧标准,不推荐,Bouncy Castle 支持 + RSA_None_ISO9796("RSA/None/ISO9796-1Padding"), + ; + + public final String code; + ALGORITHM(String code) { + this.code = code; + } + } + /** * 生成密钥对 * @@ -347,9 +383,13 @@ public class RSA { */ private Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException { Cipher cipher; - if ("RSA".equals(transformation) && isChangeSign) { + if (transformation.startsWith("RSA") && isChangeSign) { // 每次改变加密结果 - cipher = Cipher.getInstance(transformation); + if (ALGORITHM.RSA_ECB_SHA3_256.code.equals(transformation)) { + cipher = Cipher.getInstance(transformation, "BC"); + } else { + cipher = Cipher.getInstance(transformation); + } } else { Security.addProvider(new BouncyCastleProvider()); // 算法/模式/填充组合;提供者名称(如 "BC" 表示Bouncy Castle) @@ -368,17 +408,16 @@ public class RSA { try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { int offSet = 0; byte[] buff; - int i = 0; while (datas.length > offSet) { - if (datas.length - offSet > maxBlock) { - buff = cipher.doFinal(datas, offSet, maxBlock); - } else { - buff = cipher.doFinal(datas, offSet, datas.length - offSet); + // 确保不会超出数据范围 + int currentBlockSize = Math.min(maxBlock, datas.length - offSet); + if (currentBlockSize <= 0) { + break; // 防止无限循环 } + buff = cipher.doFinal(datas, offSet, currentBlockSize); out.write(buff, 0, buff.length); - i++; - offSet = i * maxBlock; + offSet += currentBlockSize; } return out.toByteArray();