百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

ECC加密算法Illegal key size错误源码详解

ztj100 2025-08-01 22:14 3 浏览 0 评论

最近在做一个新的需求,开发中使用了ECC加密算法。在以前的项目中使用的比较多加密算法是诸如RSA、AES这类算法,ECC算法还真是第一次出现在我的代码中。第一次写一个新的技术时总会遇见一些意向不到的问题。

为什么选择ECC算法呢?相较于RSA,ECC加密算法的安全性更高一些,而且加密的文件会小一些。这些都不是最重要的,主要是为了以后使用密钥协商ECDH算法方便啦!

关于算法选择咱们先不讨论那么多,我们回归到主题来,看看在使用ECC的过程中遇到了的问题。

下面是我的测试用例:

static {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}

public static void main(String[] args) {
    try {
        // 加密密钥的算法和安全模式
        KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "BC");
        // ECC曲线
        ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256r1");
        generator.initialize(ecGenParameterSpec, new SecureRandom());
        KeyPair keyPair = generator.generateKeyPair();
        // 获取公钥用于加密
        PublicKey publicKey = keyPair.getPublic();
        Cipher cipher = Cipher.getInstance("ECIES", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 加密数据
        byte[] bytes = cipher.doFinal("hello world".getBytes());
    } catch (Exception e) {
        logger.error("error", e);
    }
}

这里有一个需要注意的点:

在JAVA的标准加密库中是默认支持RSA、AES等加密算法的,但是它不支持ECC。因此我们需要添加个工具库。这个工具库就是Bouncy Castle (BC)。

如果不添加这个Provider,你可能会看到下面这个报错:

java.security.NoSuchProviderException: no such provider: BC

添加BC需要添加依赖,依赖的版本号大家可以自行寻找最新的:

 <dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15to18</artifactId>
    <version>1.63</version>
</dependency>

看似代码没啥问题了,但是一run起来,就报出了下面的错误:

java.security.InvalidKeyException: Illegal key size or default parameters

这个看代码真没看出来,只能源码走一波啦!

首先定位报错的代码行:

 Cipher cipher = Cipher.getInstance("ECIES", "BC");

下图是这一行的源码,真正执行的是划红线的一行:

继续往下看,找到了关键的代码,就是下图红框中的代码,这个var10就是返回的实例对象

断点查看var10这个变量的值,发现了一个很关键的属性【maxKeySize

从这里我们就能找到报错的原因了,实例化的对象限制了key的最大值是128,但是我生成的ECC密钥是256,所以报错Illegal key size。

找到这里虽然知道报错的原因了,但是还没有找到根因呢,作为一个爱学习的程序员,必须往下继续看看。

在var10变量之前有下面这段代码,里面有个关键的对象JceSecurity,这个对象里面维护了一个defaultPolicy,它是var10里面属性的来源。

找到defaultPolicy赋值的地方,源码如下:

断点查看结果,加载的文件是local_policy.jar,上文中128限制的对象就是var8中最后一个value值,也就是*的那个,看到了吗?

那么根因就是这个policy文件了,它是jdk中的一个文件。

查看我的JDK版本:

考虑升级版本(这是重点,也是解决办法!其实是先找高版本的同事帮忙测了一下,哈哈哈),升级成如下的版本,可以更高一些:

ECC加密算法执行成功啦!

此时必须不能就此打住,我们再来看看高版本的jdk中实例化的对象是啥样的?如下图所示,key长度限制这么大那不就是不限制了嘛!

看到这里,你明白了吗?反正我明白了,嘻嘻嘻

想了解更多详情的同学可以自己debug走一遍喔,要陪娃去了,下次更新就是下次啦!

相关推荐

Java的SPI机制详解

作者:京东物流杨苇苇1.SPI简介SPI(ServiceProvicerInterface)是Java语言提供的一种接口发现机制,用来实现接口和接口实现的解耦。简单来说,就是系统只需要定义接口规...

90%的Java程序员都忽视的内部类使用不当导致内存泄露!

...

一文读懂 Spring Boot 启动原理,开发效率飙升!

在当今的Java开发领域,SpringBoot无疑是最热门的框架之一。它以其“约定大于配置”的理念,让开发者能够快速搭建和启动应用,极大地提高了开发效率。但是,你是否真正了解Spring...

ServiceLoader

ServiceLoader是Java提供的一种服务发现机制(ServiceProviderInterface,SPI)...

深入探索 Spring Boot3 中的自定义扩展操作

在当今互联网软件开发领域,SpringBoot无疑是最受欢迎的框架之一。随着其版本迭代至SpringBoot3,它为开发者们带来了更多强大的功能和特性,其中自定义扩展操作更是为我们在项目开发中...

Spring Boot启动过程全面解析:从入门到精通

一、SpringBoot概述SpringBoot是一个基于Spring框架的快速开发脚手架,它通过"约定优于配置"的原则简化了Spring应用的初始搭建和开发过程。...

Spring Boot 3.x 自定义 Starter 详解

今天星期六,继续卷springboot3.x。在SpringBoot3.x中,自定义Starter是封装和共享通用功能、实现“约定优于配置”理念的强大机制。通过创建自己的Starte...

Spring Boot 的 3 种动态 Bean 注入技巧

在SpringBoot开发中,动态注入Bean是一种强大的技术,它允许我们根据特定条件或运行时环境灵活地创建和管理Bean。相比于传统的静态Bean定义,动态注入提供了更高的灵活性和可...

大佬用4000字带你彻底理解SpringBoot的运行原理!

SpringBoot的运行原理从前面创建的SpringBoot应用示例中可以看到,启动一个SpringBoot工程都是从SpringApplication.run()方法开始的。这个方法具体完成...

Springboot是如何实现自动配置的

SpringBoot的自动配置功能极大地简化了基于Spring的应用程序的配置过程。它能够根据类路径中的依赖和配置文件中的属性,自动配置应用程序。下面是SpringBoot实现自动配置的...

Spring Boot3.x 应用的生命周期深度解析

SpringBoot应用的生命周期可以清晰地划分为三个主要阶段:启动阶段(Startup)...

Springboot 启动流程及各类事件生命周期那点事

前言本文通过Springboot启动方法分析SpringApplication逻辑。从静态run方法执行到各个阶段发布不同事件完成整个应用启动。...

Spring框架基础知识-常用的接口1

BeanDefinition基本概念BeanDefinition是Spring框架中描述bean配置信息的核心接口,它包含了创建bean实例所需的所有元数据。...

一家拥有 158 年历史的公司遭遇索赔,被迫关闭!

...

Java 技术岗面试全景备战!从基础到架构的系统性通关攻略分享

Java技术岗的面试往往是一项多维度的能力检验。本文将会从核心知识点、项目经验到面试策略,为你梳理一份系统性的备战攻略!...

取消回复欢迎 发表评论: