目录

  • Java持久化秘钥
    • 1 保存PEM文件
    • 2 保存文本文件
    • 3 Java序列化

Java持久化秘钥

加密算法的秘钥持久化是是一个不可避免的话题,如何安全的存储更是重中之重。将秘钥保存在文件中是最简单的一种方法,下面来讨论如何使用Java代码将秘钥保存到文件中。

保存到文件中的秘钥最好用PBE进行口令加密。

下面介绍几种简单的保存秘钥的方式,以RSA秘钥为例。

1 保存PEM文件

PEM(Privacy Enhanced Mail)格式是一种安全的文件格式,主要用于存储证书、密钥和其他数据。它的格式遵循Base64编码规则,以“-----BEGIN CERTIFICATE-----“和”-----END CERTIFICATE-----"两句作为文件头尾标识。

-----BEGIN RSA PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCSpS0Ulc4uZFcq
0F5/1BFajwfzOLl/ToDFa46HdOotyK3pMSG0xjqVea2fc1Ufh1E+pDZBx6Fe/7rX
Ceqjx/77dxcgRJzI6yUb/EVuVSKSFL8wXFe/30HvmCIbyybJN393BrO3JJ6VvGIC
RUurvUlHR9Z6Rxil18XZ7oi4WlaJ15JPE/e1o2J1S0q5slUBA1icyrIPztV0NULQ
qExB5KmXwGDhm9sXUpBbAWc5oO5Ua+z8a8iiJ3qhK/iPyuUtnAJLkPma1Q++qOPv
dIrftw8rWpbbklu9X/cjoFbLPlx0MJhygNRoyV5BkCSj++77P5zh3H6x95gBNCaR
Hx10y+KpAgMBAAECggEBAIiZMhflv2w5bXTlKdGawht/9mDaavgqMQs0uEx3XJgP
QehhKsuQhwurj05jCVzYGJboMd4uTaQHRIyAoT+00VB+S110bDM/zo51/FrdFNnM
V5d9vQNuvKWpKcSIBPYUKzi9VnR3uP0zwHvq/qTYKkUqpp+6UDxTdOofJt3K0KeO
ZL+gFe7vSR0oioP+FJ4zrLVxsmRoqFz9Q+xtg4Md2/T5JsB0gNAD5ljFia8u1bNL
rR3IPcy/a4/5k2SqsLEIxiGKiijpvJw3Gj6/gDQXjpwTcx2GZIqYacZU9YjKoWi3
gAPFiEHNKH0/ZREsb+TFAKAaVS5SYhsir+EaYBmWZo0CgYEA7u4gYCXbYJ0+qIcL
L9xCOOeKxBkohgZ7gVOrE6AgsXdb9XmVtD9Ab1NVYVBSH7FzhRTGXd8fPsjRUwxD
PLY4O8ZjECp/aKl0oXtfxIWZTBlWyE1ztEidK+zAbPsd/cEZKWwmUKShPBMhQTFc
EBy9P9ax+tKlB1An138gdMur3Y8CgYEAnR84Id33ze06WSL6td0qhOvtTClRwxc7
c9N6YWCdJ2viDbEeo/4MW3WRKoNodZD6ivb3uXPma5yM1j26mnC3SLBlBzXvvG+w
M1DJHbZnRVwFdmVAhlCjbMlSIty+dIzm3JMNH6yzajYVI1iElVCCe8CJ9TC3PrLD
mzQ4kN3vkEcCgYAcbtwNdRPZOH03YvKy3FxJF0zNL01CPc0+w60tJbYeSFz6JmDp
VUmeteUIMp3DRcPAh4tfqmi2eQFoB6KMvAaPHnm1d8k3tEq72Mm5wkhO5QkNxyHI
x4dkrcTscynLg8oxwrwAhsblNkWT04LoK/NdgHgnqB+ZcjF7lJZRL9ehAwKBgQCV
2biHVFOKqr4DVUEXQh/TNc/T23SHRBkHlqIZTTOU7Wdi95HphdnzQGV6zmlJ90N8
VZ5d2RPhfiU0DxtxQB8NzG4OOnqylTLPPjURiW1k0SbEjDzF3RKAJmGXrkBWmCt2
IylZFDTpDzuJwlpwraBEtpTcq+GYgpXb6CoqwABC8QKBgQCunTRpMSm/NvmKAXSW
YWiR8TyJ0YxSiF58FZoEWHuz3/u96NHaQQgDd5m0WxlubUi2aJPdHQRZ3Pw/oZFp
BrJxN3WJdf36caYylN9LvoizGZezeK1gheJBhkfXhfvo9SQfvzQjyM5bHEnrOoFD
bW31uKY0VMqjhMEqqbJf808lsA==
-----END RSA PRIVATE KEY-----

PEM格式的证书包含数字证书(如SSL证书)、密钥、CSR(Certificate Signing Request)和其他文件。

PEM文件通常以.pem, .crt, .cer, .key等扩展名命名。

package com.qupeng.crypto.util;import org.bouncycastle.util.Strings;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.*;public class SecretKeyPersistence {public static void writePublicKeyToPem(PublicKey publicKey, Path keyFilePath) throws IOException {try (FileWriter fileWriter = new FileWriter(keyFilePath.toFile()); PemWriter pemWriter = new PemWriter(fileWriter)) {pemWriter.writeObject(new PemObject("RSA PUBLIC KEY", publicKey.getEncoded()));}}public static PublicKey readPublicKeyFromPem(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {try (FileReader fileReader = new FileReader(keyFilePath.toFile()); PemReader pemReader = new PemReader(fileReader)) {PemObject pemObject = pemReader.readPemObject();X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(pemObject.getContent());PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(encPubKeySpec);return publicKey;}}public static void writePrivateKeyToPem(PrivateKey privateKey, Path keyFilePath) throws IOException {try (FileWriter fileWriter = new FileWriter(keyFilePath.toFile()); PemWriter pemWriter = new PemWriter(fileWriter)) {pemWriter.writeObject(new PemObject("RSA PRIVATE KEY", privateKey.getEncoded()));}}public static PrivateKey readPrivateKeyFromPem(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {try (FileReader fileReader = new FileReader(keyFilePath.toFile()); PemReader pemReader = new PemReader(fileReader)) {PemObject pemObject = pemReader.readPemObject();PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(pemObject.getContent());PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(encPriKeySpec);return privateKey;}}
}

引入bouncycastle依赖

        <dependency><groupId>org.bouncycastle</groupId><artifactId>bcpg-jdk18on</artifactId><version>1.72</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk18on</artifactId><version>1.72</version></dependency>

2 保存文本文件

将秘钥保存到普通的文本文件中。

package com.qupeng.crypto.util;import org.bouncycastle.util.Strings;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.*;public class SecretKeyPersistence {public static void writePublicKeyToTxt(PublicKey publicKey, Path keyFilePath) throws IOException {Files.write(keyFilePath, new BASE64Encoder().encode(publicKey.getEncoded()).getBytes(), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);}public static PublicKey readPublicKeyFromTxt(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(new BASE64Decoder().decodeBuffer(Strings.fromByteArray(Files.readAllBytes(keyFilePath))));PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(encPubKeySpec);return publicKey;}public static void writePrivateKeyToTxt(PrivateKey privateKey, Path keyFilePath) throws IOException {Files.write(keyFilePath, new BASE64Encoder().encode(privateKey.getEncoded()).getBytes(), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);}public static PrivateKey readPrivateKeyFromTxt(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(Strings.fromByteArray(Files.readAllBytes(keyFilePath))));PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(encPriKeySpec);return privateKey;}
}

3 Java序列化

这里利用Java系列保存类 RSAPublicKeySpec。RSAPublicKeySpec用于描述秘钥规格。

package com.qupeng.crypto.util;import org.bouncycastle.util.Strings;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.*;public class SecretKeyPersistence {public static void writePublicKeyToObj(PublicKey publicKey, Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(keyFilePath.toFile())))) {KeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPublicKeySpec rsaPublicKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);objectOutputStream.writeObject(rsaPublicKeySpec.getModulus());objectOutputStream.writeObject(rsaPublicKeySpec.getPublicExponent());}}public static PublicKey readPublicKeyFromObj(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, ClassNotFoundException {try (ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(keyFilePath.toFile())))) {BigInteger modulus = (BigInteger)objectInputStream.readObject();BigInteger exponent = (BigInteger)objectInputStream.readObject();RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return keyFactory.generatePublic(rsaPublicKeySpec);}}public static void writePrivateKeyToObj(PublicKey privateKey, Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(keyFilePath.toFile())))) {KeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPublicKeySpec rsaPublicKeySpec = keyFactory.getKeySpec(privateKey, RSAPublicKeySpec.class);objectOutputStream.writeObject(rsaPublicKeySpec.getModulus());objectOutputStream.writeObject(rsaPublicKeySpec.getPublicExponent());}}public static PrivateKey readPrivateKeyFromObj(Path keyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, ClassNotFoundException {try (ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(keyFilePath.toFile())))) {BigInteger modulus = (BigInteger)objectInputStream.readObject();BigInteger exponent = (BigInteger)objectInputStream.readObject();RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return keyFactory.generatePrivate(rsaPrivateKeySpec);}}
}

Java加解密(十)持久化秘钥相关推荐

  1. 60分钟搞定JAVA加解密

    从摩尔电码到小伙伴之间老师来了的暗号,加密信息无处不在.从军事到生活,加密信息的必要性也不言而喻. 今天,我们就来看看java怎么对数据进行加解密 分类 a.古典密码 -- 受限制算法:算法的保密性给 ...

  2. Java加解密的艺术书摘

    Java加解密的艺术 密码学常用术语 明文(Plaintext):指待加密信息.明文可以是文本文件.图片文件.二进制数据等. 密文(Ciphertext):指经过加密后的明文.密文通常以文本.二进制数 ...

  3. erlang java 加解密(2)消息摘要算法(MD、SHA、MAC)之SHA

    java加解密相关资料和代码参考<java加密与解密的艺>http://snowolf.iteye.com/blog/379860 sha(Data) -> Digest Types ...

  4. crypto-js 前端DES加密/解密、生成秘钥 详解

    DES概述 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非 ...

  5. Java加解密(八)PGP协议

    目录 PGP协议 1 PGP提供的操作 1.1 身份识别 1.2 机密性 1.3 机密性与鉴别 1.4 电子邮件的兼容性 1.5 压缩 1.6 分段和重装 2 加密密钥和密钥环 2.1 公钥环 2.2 ...

  6. Java 加解密技术系列之 RSA

    序 距离上一次写博客感觉已经很长时间了,先吐槽一下,这个月以来,公司一直在加班,又是发版.上线,又是新项目太紧,具体的就不多说了,想听我吐槽的小伙伴,可以私信给我(*^__^*) .上一篇文章,已经把 ...

  7. Java 加解密工具类

    一.对称加密算法  加密和解密使用相同密钥的加密算法.常用的算法包括DES.3DES.AES.DESX.Blowfish.RC4.RC5.RC6. DES(Data Encryption Standa ...

  8. [JAVA加解密]RSA算法、ElGamal算法

    一.RSA算法: 1.简介:RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的. ...

  9. java 3des解密过程_6. Java 加解密技术系列之 3DES

    importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.spec.SecretKeySpec;importj ...

最新文章

  1. docker安装mysql并实现远程访问
  2. 设置VMWARE通过桥接方式使用主机无线网卡上网
  3. 打印5列五颗星_13个Excel快捷打印技巧,让你熟练掌握打印机操作
  4. python没有错误但是不显示结果_为什么我在Python3中加载模块时遇到问题但在Python2中没有加载?...
  5. 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波1 - 灰度变换和空间滤波基础、Sigmoid激活函数
  6. 六、Webpack详解学习笔记——webpack的安装、起步、配置、loader的使用、webpack中配置Vue、plugin的使用、搭建本地服务器、webpack配置的分离
  7. 2020年最快的dns_2020年哪里换旅行证最快取证?需要几天?
  8. 别再用硬编码写业务流程了,试试这款轻量级流程编排框架
  9. mescroll.js -- 精致的下拉刷新和上拉加载js框架
  10. 实现Excel实现下拉框选择对应的数据(数据验证)
  11. 春季校园招聘简历投递量已超去年同期;亚太房地产市场现逢低买入良机 | 美通企业日报...
  12. Linux 流量监控
  13. 清北学堂集训day1
  14. mybatis 一对一、一对多、多对一、多对多
  15. linux如何查找下一个
  16. 近期全球知识图谱相关行业动态、会议讲座、综述推荐
  17. step(stp)文件导入ANSYS 2020 R2 workbench Geometry的方法
  18. 视频尺寸修改的小方法,同时处理多个视频,新媒体必备
  19. Lattice ddr3教程全攻略之时序约束篇
  20. ActiveX控件的注册和反注册

热门文章

  1. 关于JS中的浮点数运算
  2. 腾讯音乐Q3财报前瞻:业绩驶入加速区,业务释放强劲向上动力
  3. 程序员职业病之中医颈椎痛缓解办法
  4. 2022buaa数据结构_1TH_1.扩展字符
  5. CRECT,RECT区别GetWindowRect GetClientRect
  6. Reason: Failed to determine a suitable driver class
  7. whisper实践--基于whisper+pyqt5开发的语音识别翻译生成字幕工具
  8. C语言:菜鸟教程经典100例题(1-50)
  9. Oracle: archive归档速度控制尝试
  10. 写给想学和在学编程的你们,学习编程的7个好处