如何不使用getInstance方法手动构建Cipher加密实例
首先明确:Java标准javax.crypto.Cipher没有公开构造方法
JDK的Cipher设计上是基于JCE Provider架构的封装类,本身只暴露对外接口,具体实现完全由注册的加密提供者提供,因此不可能直接通过new Cipher(AESEngine)的方式实例化。你要实现自定义组件组装的需求,有两种可行路径:
方案1:遵循JCE规范实现自定义提供者
如果需要兼容标准Cipher接口,你需要完成整套JCE扩展实现:
- 继承
CipherSpi抽象类,在你的实现类中预留入口,支持传入自定义分组引擎、工作模式、填充实现 - 自定义
Provider类,将你的CipherSpi实现和自定义算法名称绑定 - 将自定义Provider注册到JRE的加密提供者列表中,之后就可以通过
Cipher.getInstance("你的自定义算法名", "你的自定义Provider名")获取你实现的Cipher实例
该方案完全兼容JDK的加密生态,但实现成本高,需要处理大量规范要求的校验、异常逻辑,适合生产环境需要接入现有JCE体系的场景。
方案2:直接使用加密库底层API(学习首选)
如果只是为了学习密码组件的组装逻辑,不需要兼容标准Cipher接口,直接使用BouncyCastle等加密库的底层组件即可,所有模块都可以手动实例化、自由组合:
import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.GCMBlockCipher; import org.bouncycastle.crypto.paddings.BlockCipherPadding; // 1. 手动实例化分组密码核心 AESEngine aesEngine = new AESEngine(); // 2. 手动指定工作模式 GCMBlockCipher gcmCipher = new GCMBlockCipher(aesEngine); // 如果使用需要填充的模式(如CBC),可以自行传入自定义填充实现,只要实现BlockCipherPadding接口即可 // import org.bouncycastle.crypto.modes.CBCBlockCipher; // import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; // CBCBlockCipher cbcCipher = new CBCBlockCipher(aesEngine); // BlockCipherPadding customPadding = new 你自己实现的填充类(); // PaddedBufferedBlockCipher paddedCipher = new PaddedBufferedBlockCipher(cbcCipher, customPadding);
这种方式完全符合你想要手动指定每一层组件的需求,不需要适配JCE的工厂模式约束,非常适合学习密码学工作原理。
内容的提问来源于stack exchange,提问作者Ruohonleikkuri
相关产品推荐
相关产品推荐

