转载备份
影子 DOM(Shadow DOM)
你的 docker stop,它优雅吗? - 无糖拿铁,谢谢
清理Docker的container,image与volume · 零壹軒·笔记
Create a PyPI Mirror Site with devpi-server – SRE
优雅的终止 docker 容器 | iTimothy
Odoo 14 开发者指南第二十一章 性能优化 | Alan Hou 的个人博客
Odoo 14 开发者指南第八章 高级服务端开发技巧 | Alan Hou 的个人博客
kafka 系列:设置日志数据保存过期时间(含某个 topic)、日志策略_NIO4444-CSDN 博客_kafka 配置数据过期时间
Chromium 历史版本离线安装包 - 下载方法
怎样将 props 传递给 {this.props.children} | WebFuse
HappyBaseDoc
用户指南 — HappyBase 1.2.0 文档
安装指南 — HappyBase 1.2.0 文档
API 参考 — HappyBase 1.2.0 文档
PostgreSQL 时间转换
JS 中创建给定长度的数组
GSAP 入门 - 学习中心 - 绿袜
操作系统复习 | Happy Coding
如何理解 ip 路由和操作 linux 的路由表 - CodeAntenna
Elasticsearch 7.11 tokenizer, analyzer and filter 以及 IK 分词配置同义词、远程拓展词库 – Brave new world
podman 容器内访问 host 主机的端口 - 知识库 - BSMI KB 基础标准矿产工业
吐血总结!100 道经典 Python 面试题集锦上(附答案)
中共党史简表(1919 年 - 1949 年)
Dockerfile 详解_万 wu 皆可爱的博客 - CSDN 博客_dockerfile
为你的 Python 应用选择一个最好的 Docker 映像 | 亚马逊 AWS 官方博客
Ubuntu Server 支持中文
docker push | Docker Documentation
docker 创建本地仓库详解 (push/pull)_乱红飞的博客 - CSDN 博客_docker push 本地仓库
基于 Ubuntu 20.04 安装 Kubernetes 1.18
PostgreSQL 集群篇——PostgreSQL 的配置文件解析_51CTO 博客_postGresql
【PostgreSQL】——主从流复制_Teingi 的博客 - CSDN 博客_postgresql 主从复制
PostgreSQL: Documentation: 14: 27.4. Hot Standby
postgresql 主从复制、主从切换_偷懒的小陈的博客 - CSDN 博客_postgresql 主从
Postgres 用户、角色与权限 :: 68hub — 技术博客
中国共产党第二十次全国代表大会在京开幕 一图速览二十大报告
配置 docker 通过代理服务器拉取镜像
IPVS no destination available - Kubernetes 实践指南
Python 风格规范 — Google 开源项目风格指南
互动测试!党的二十大报告 100 题
自定义 ESlint 规则
Java 读取 OpenSSL 生成的秘钥, 进行 RSA 加解密 | 数字魔法
CSS(一)chrome 浏览器表单自动填充默认样式 - autofil_半个 GIS 半个前端的博客 - CSDN 博客
Nginx 多级代理下的真实 IP 透传 - CodeAntenna
Jenkins 环境变量
人民币金额大写规范 - 内蒙古农业大学财务处
[转]nginx 开启 websocket - 浅忆博客
ceph 创建使用 rbd
《三》配置 ceph 存储池 pool - Buxl's blog
基于 K8S 搭建 Ceph 分部署存储 – 唐玥璨 | 博客
序言 · Kubernetes 中文指南——云原生应用架构实战手册
服务器配置 - Redis 安装配置 | 灰帽子 - 任令仓的技术博客
Ubuntu 配置 sudo 命令不需要输入密码_ubuntu sudo 免密_一路向前 - 执着的博客 - CSDN 博客
修改 Docker 数据目录位置,包含镜像位置 - 腾讯云开发者社区 - 腾讯云
微服务架构实践(API Gateway)
微服务网关:从对比到选型,由理论到实践 | Java 程序员进阶之路
聊聊微服务网关
微服务网关:从对比到选型,由理论到实践
odoo 实现表分区 partition
使用 keepalived 搭建高可用服务 - 简书
业务网关的落地实践_文化 & 方法_Qunar 技术沙龙_InfoQ 精选文章
部署 Kubernetes PostgreSQL 实例 | domac 的菜园子
一套包含完整前后端的系统如何在 K8S 中部署?_k8s 前端_木讷大叔爱运维的博客 - CSDN 博客
前端安全系列(二):如何防止 CSRF 攻击? - 美团技术团队
traefik 自定义中间件 | coolcao 的小站
CSRF 原理和实战利用 - FreeBuf 网络安全行业门户
安全运维 - 如何在 Kubernetes 中使用注释对 ingress-nginx 及后端应用进行安全加固配置实践_唯一极客知识分享的技术博客_51CTO 博客
Kubernetes 进阶使用之 Helm,Kustomize
各种加密算法比较
Docker 的三种网络代理配置 · 零壹軒 · 笔记
本文档使用 MrDoc 发布
-
+
首页
Java 读取 OpenSSL 生成的秘钥, 进行 RSA 加解密 | 数字魔法
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [zxcsoft.com](https://zxcsoft.com/java/SpringBoot/2020-06-22.html#_2-2-pkcs1-%E7%A7%81%E9%92%A5%E8%BD%AC%E6%8D%A2%E4%B8%BA-pkcs8) OpenSSL 生成的秘钥与 java RSA 加解密类生成的秘钥类型不一致, 导致加载秘钥失败. 通过引入一个工具包. 来实现加解密 1. 生成秘钥 ------- ### 1.1 使用`OpenSSL`生成秘钥 ``` openssl genrsa -out rsa_private_key.pem 1024 ``` ### 1.2 查看私钥 ``` -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQCtSXcCfb5pJ/CrOWDAdHVEO8wzoj/Waskia3T9nBOXJKbf1TqT S7bn8m/2kn/bx0p8FuK+LcH2TeCNa5DXyCE+k+qkqCXTI6U48aSKjzZ0eiCPRDm0 ZfdCJoB3l7rxOx2jO/EXtjXC3VrX0vddjR/3AGDm/TUmlIkm0IpHzdPSAwIDAQAB AoGBAI0KxKD0c+znI05aL1O19lSJT1Wfc9IzrG4lhF1/kbptjJ2W0kxdTgxQGa1Z 5FOgTBHgFsGwQLUXAfRZXtUjAVq0sEVFzM0rWRr8B63UFokY198jL/1XgcgAp8jP BbJRI1Mp/TdNtsdkK4bE/6pJsZrlLCpsA9uz91AaddN60bhRAkEA2t3Sk1aqfwSP Delwv96nFwgb8XbZ5i4BgHp4UDFyoW/g6VhaLEOyM+VBUOK4iVKaNOZdtdFazlrS NhFY18iyxwJBAMqv9LZNeDajQ2Hju1B8/ZV2plCROh8Jvy7Dike6BI/NvVgm/h9O dsZzqenlMX24232Sl4WnUBH+gr6DzwsO6uUCQQCroMdAQvXwJOMJRcXkr/TXWsSO 1WSJ3AnRdjhiqmP5tIHqeh48F9nmWCCgDSoohV3nnb5elY1fxFiTjYbdr8SBAkBW MBRDIRYpRat1iL0yMLQ0Rkvanqa0ZBSj8gpvDa6656XIQmx1K4xePvjVuNwetei/ sQI1lzv5Kty13p6/+QvxAkEArSPbBXRhFKVKiR9tvvz87UYA4bchiuDseGWhqB6H 37grzW5eGPfd8CAoJKWp2CmZa1Ad86+YRXvWwKhE5/vBpg== -----END RSA PRIVATE KEY----- ``` ### 1.3 生成查看公钥 ``` openssl rsa -in rsa_private_key.pem -out rsa_public_key_1024.pub -pubout ``` ``` -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtSXcCfb5pJ/CrOWDAdHVEO8wz oj/Waskia3T9nBOXJKbf1TqTS7bn8m/2kn/bx0p8FuK+LcH2TeCNa5DXyCE+k+qk qCXTI6U48aSKjzZ0eiCPRDm0ZfdCJoB3l7rxOx2jO/EXtjXC3VrX0vddjR/3AGDm /TUmlIkm0IpHzdPSAwIDAQAB -----END PUBLIC KEY----- ``` ### 1.4 加解密引入包 ``` <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.56</version> </dependency> ``` ### 1.5 加解密代码 ``` import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.X509EncodedKeySpec; @Component @Slf4j public class RSAUtil { @Value("${config.rsa.privateKey}") private String privateKey; @Value("${config.rsa.publicKey}") private String publicKey; public static void main(String[] args) { RSAUtil rsaUtil = new RSAUtil(); rsaUtil.publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtSXcCfb5pJ/CrOWDAdHVEO8wzoj/Waskia3T9nBOXJKbf1TqTS7bn8m/2kn/bx0p8FuK+LcH2TeCNa5DXyCE+k+qkqCXTI6U48aSKjzZ0eiCPRDm0ZfdCJoB3l7rxOx2jO/EXtjXC3VrX0vddjR/3AGDm/TUmlIkm0IpHzdPSAwIDAQAB"; rsaUtil.privateKey = "MIICXgIBAAKBgQCtSXcCfb5pJ/CrOWDAdHVEO8wzoj/Waskia3T9nBOXJKbf1TqTS7bn8m/2kn/bx0p8FuK+LcH2TeCNa5DXyCE+k+qkqCXTI6U48aSKjzZ0eiCPRDm0ZfdCJoB3l7rxOx2jO/EXtjXC3VrX0vddjR/3AGDm/TUmlIkm0IpHzdPSAwIDAQABAoGBAI0KxKD0c+znI05aL1O19lSJT1Wfc9IzrG4lhF1/kbptjJ2W0kxdTgxQGa1Z5FOgTBHgFsGwQLUXAfRZXtUjAVq0sEVFzM0rWRr8B63UFokY198jL/1XgcgAp8jPBbJRI1Mp/TdNtsdkK4bE/6pJsZrlLCpsA9uz91AaddN60bhRAkEA2t3Sk1aqfwSPDelwv96nFwgb8XbZ5i4BgHp4UDFyoW/g6VhaLEOyM+VBUOK4iVKaNOZdtdFazlrSNhFY18iyxwJBAMqv9LZNeDajQ2Hju1B8/ZV2plCROh8Jvy7Dike6BI/NvVgm/h9OdsZzqenlMX24232Sl4WnUBH+gr6DzwsO6uUCQQCroMdAQvXwJOMJRcXkr/TXWsSO1WSJ3AnRdjhiqmP5tIHqeh48F9nmWCCgDSoohV3nnb5elY1fxFiTjYbdr8SBAkBWMBRDIRYpRat1iL0yMLQ0Rkvanqa0ZBSj8gpvDa6656XIQmx1K4xePvjVuNwetei/sQI1lzv5Kty13p6/+QvxAkEArSPbBXRhFKVKiR9tvvz87UYA4bchiuDseGWhqB6H37grzW5eGPfd8CAoJKWp2CmZa1Ad86+YRXvWwKhE5/vBpg=="; System.out.println(rsaUtil.encrypt("李四")); System.out.println(rsaUtil.encrypt("123456789012345678")); System.out.println("李四".equals(rsaUtil.decrypt(rsaUtil.encrypt("李四")))); } public String encrypt(String str) { try { //base64编码的公钥 byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { log.error("encrypt failed: str[" + str + "], publicKey[" + publicKey + "]"); throw new RunTimeException("解密失败", e); } } public String decrypt(String str) { try { //64位解码加密后的字符串 byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); //base64编码的私钥 byte[] decoded = Base64.decodeBase64(privateKey); org.bouncycastle.asn1.pkcs.RSAPrivateKey rsaPrivateKey = org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(decoded); RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent()); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(rsaPrivKeySpec); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); return new String(cipher.doFinal(inputByte)); } catch (Exception e) { log.error("decrypt failed: str[" + str + "], privateKey[" + publicKey + "]", e); throw new RunTimeException("解密失败", e); } } } ``` ### 1.6 `RSA`秘钥类型说明 公钥加密标准(Public Key Cryptography Standards, PKCS) <table><thead><tr><th>PKCS</th><th>版本</th><th>名称</th><th>简介</th></tr></thead><tbody><tr><td>PKCS #1 [^1]</td><td>2.1</td><td>RSA 密码编译标准(RSA Cryptography Standard)</td><td>定义了 RSA 的数理基础、公 / 私钥格式,以及加 / 解密、签 / 验章的流程。1.5 版本曾经遭到攻击。</td></tr><tr><td>PKCS #2</td><td>-</td><td>撤销</td><td>原本是用以规范 RSA 加密摘要的转换方式,现已被纳入 PKCS#1 之中。</td></tr><tr><td>PKCS #3</td><td>1.4</td><td>DH 密钥协议标准(Diffie-Hellman key agreement Standard)</td><td>规范以 DH 密钥协议为基础的密钥协议标准。其功能,可以让两方通过金议协议,拟定一把会议密钥 (Session key)。</td></tr><tr><td>PKCS #4</td><td>-</td><td>撤销</td><td>原本用以规范转换 RSA 密钥的流程。已被纳入 PKCS#1 之中。</td></tr><tr><td>PKCS #5</td><td>2.0</td><td>密码基植加密标准(Password-based Encryption Standard)</td><td>参见 RFC 2898 与 PBKDF2。</td></tr><tr><td>PKCS #6</td><td>1.5</td><td>证书扩展语法标准(Extended-Certificate Syntax Standard)</td><td>将原本 X.509 的证书格式标准加以扩充。</td></tr><tr><td>PKCS #7</td><td>1.5</td><td>密码消息语法标准(Cryptographic Message Syntax Standard)</td><td>参见 RFC 2315。规范了以公开密钥基础设施(PKI)所产生之签名 / 密文之格式。其目的一样是为了拓展数字证书的应用。其中,包含了 S/MIME 与 CMS。</td></tr><tr><td>PKCS #8 [^2]</td><td>1.2</td><td>私钥消息表示标准(Private-Key Information Syntax Standard).</td><td>Apache 读取证书私钥的标准。</td></tr><tr><td>PKCS #9</td><td>2.0</td><td>选择属性格式(Selected Attribute Types)</td><td>定义 PKCS#6、7、8、10 的选择属性格式。</td></tr><tr><td>PKCS #10</td><td>1.7</td><td>证书申请标准(Certification Request Standard) 参见 RFC 2986。</td><td>规范了向证书中心申请证书之 CSR(certificate signing request)的格式。</td></tr><tr><td>PKCS #11</td><td>2.20</td><td>密码设备标准接口(Cryptographic Token Interface (Cryptoki))</td><td>定义了密码设备的应用程序接口(API)之规格。</td></tr><tr><td>PKCS #12</td><td>1.0</td><td>个人消息交换标准(Personal Information Exchange Syntax Standard)</td><td>定义了包含私钥与公钥证书(public key certificate)的文件格式。私钥采密码 (password) 保护。常见的 PFX 就履行了 PKCS#12。</td></tr><tr><td>PKCS #13</td><td>–</td><td>椭圆曲线密码学标准(Elliptic curve cryptography Standard)</td><td>制定中。规范以椭圆曲线密码学为基础所发展之密码技术应用。椭圆曲线密码学是新的密码学技术,其强度与效率皆比现行以指数运算为基础之密码学算法来的优秀。然而,该算法的应用尚不普及。</td></tr><tr><td>PKCS #14</td><td>–</td><td>拟随机数产生器标准(Pseudo-random Number Generation)</td><td>制定中。规范拟随机数产生器的使用与设计。</td></tr><tr><td>PKCS #15</td><td>1.1</td><td>密码设备消息格式标准(Cryptographic Token Information Format Standard)</td><td>定义了密码</td></tr></tbody></table> [^1]:`PKCS #1`为`OpenSSH`默认使用的加密标准 [^2]:`PKCS #8`为`Java`默认使用的加密标准 java 默认使用的 RSAKey ``` byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); ``` 2 `RSA`格式转换 ----------- ### 2.1 生成`PKCS1`私钥 `OpenSSL`生成`PKCS1`格式的私钥,密钥长度 1024 位 ``` openssl genrsa -out private.pem 1024 ``` ### 2.2 `PKCS1`私钥转换为`PKCS8` ``` openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem ``` ### 2.3 `PKCS8`私钥转换为`PKCS1` ``` openssl rsa -in pkcs8.pem -out pkcs1.pem ``` ### 2.4 从`PKCS1`私钥中生成`PKCS8`公钥 ``` openssl rsa -in private.pem -pubout -out public.pem ``` ### 2.5 从`PKCS8`私钥中生成`PKCS8`公钥 ``` openssl rsa -in pkcs8.pem -pubout -out public_pkcs8.pem ``` 与 2.4 生成的结果一致 ### 2.6 从`PKCS8`公钥转换`PKCS1`公钥 ``` openssl rsa -pubin -in public_pkcs8.pem -RSAPublicKey_out ``` 生成前后文件一致 ### 2.7 从`PKCS1`公钥转换`PKCS8`公钥 ``` openssl rsa -RSAPublicKey_in -in pub_pkcs1.pem -pubout ``` 生成前后文件一致
幻翼
2022年11月9日 18:19
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码