网站首页 > java教程 正文
最近在做一个新的需求,开发中使用了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走一遍喔,要陪娃去了,下次更新就是下次啦!
猜你喜欢
- 2025-04-27 Java多线程编程中的锁优化技巧:锁的艺术之旅
- 2025-04-27 基于Vue.js的http网站如何实现帐号密码加密传输?
- 2025-04-27 Java虚拟机类加载机制剖析:探秘Java世界的“魔法师”
- 2025-04-27 Springboot 配置文件、隐私数据脱敏最佳实践(原理+源码)
- 2025-04-27 Java 如何加载带密码的 PCKS8 PEM 私钥
- 2025-04-27 轻松掌握Java多线程 - 第六章:volatile关键字
- 2025-04-27 Java网络编程中的Socket通信优化之道
- 2025-04-27 Java 17中的新加密API:实现数据安全传输
- 2025-04-27 Java代码保护方法之四:JVMTI实现Java源码保护
- 2025-04-27 Java并发编程中的锁机制:掌控多线程世界的钥匙
你 发表评论:
欢迎- 04-27微服务部署架构设计详解(图文全面总结)
- 04-27Java微服务架构选型与对比:一场技术流派的巅峰对决
- 04-27微服务架构下Java的最佳实践
- 04-27Java微服务架构选型:优雅拆分与高效整合
- 04-27微服务架构下的Java代码拆分策略:像拼图一样构建系统
- 04-27微服务架构下的Java最佳实践
- 04-27微服务架构下Java的挑战与机遇
- 04-27微服务架构下Java事务管理的艺术
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)