【加密与解密】【06】Java加密套件全解析

Java中的秘钥类
  • PublicKey,公钥
  • PrivateKey,私钥
  • SecretKey,秘钥,特指对称加密中的秘钥
Key接口

上面的秘钥类均实现该接口

interface java.security.Key// DSA
fun getAlgorithm() : String// X.509
fun getFormat() : String// key content
fun getEncoded() : ByteArray
KeyPairGenerator

用于生成公钥私钥对

@OptIn(ExperimentalStdlibApi::class)
fun generateKeyPair() {val generator = KeyPairGenerator.getInstance("DSA")generator.initialize(1024)val keyPair = generator.genKeyPair()val publicKey = keyPair.publicval privateKey = keyPair.privateprintln("PublicKey:" + publicKey.encoded.toHexString(HexFormat.UpperCase))println("PrivateKey:" + privateKey.encoded.toHexString(HexFormat.UpperCase))
}
KeyGenerator

用于生成对称秘钥

@OptIn(ExperimentalStdlibApi::class)
fun generateSecretKey() {val random = SecureRandom()val generator = KeyGenerator.getInstance("DES")generator.init(random)val secretKey = generator.generateKey()println("SecretKey:" + secretKey.encoded.toHexString(HexFormat.UpperCase))
}
KeySpec

定义秘钥规格的接口,所有秘钥类参数类,都当实现该接口

  • SecretKeySpec,对称秘钥规格,支持所有对称加密算法
  • X509EncodedKeySpec,公钥规格
  • PKCS8EncodedKeySpec,私钥规格
  • DESKeySpec,DES算法加密的秘钥规格
  • SecretKeySpec本身可以直接作为Key来使用,其它Spec则不可以
  • 可以通过KeyFactory.generate(spec)来生成Key
  • 大多KeySpec根据bytes参数进行初始化
AlgorithmParameterSpec

定义算法规格的接口,所有算法参数类,都当实现该接口

  • DSAParameterSpec,DSA算法参数规格
  • 可以通过KeyGenerator.init(spec)来应用算法参数
  • 大多ParameterSpec根据algorithm,random,offset等参数初始化
KeyFactory

非对称秘钥工厂

根据KeySpec生成公钥私钥,或公钥私钥生成KeySpec

val spec = PKCS8EncodedKeySpec(keyBytes)
val factory = KeyFactory.getInstance("RSA")
val key = factory.generatePrivate(spec)
println("PrivateKey:" + key.encoded.toHexString())
val key = factory.getKeySpec(key, PKCS8EncodedKeySpec::class.java)
SecretKeyFactory

对称秘钥工厂

和KeyFactory用法完成一致,只是对应的秘钥类型不一样

@OptIn(ExperimentalStdlibApi::class)
fun generateSecretKey() {val generator = KeyGenerator.getInstance("DES")val secretKey1 = generator.generateKey()val keyBytes = secretKey1.encodedval keySpec = DESedeKeySpec(keyBytes)val keyFactory = SecretKeyFactory.getInstance("DES")val secretKey2 = keyFactory.generateSecret(keySpec)println(secretKey1.encoded.toHexString(HexFormat.UpperCase))println(secretKey2.encoded.toHexString(HexFormat.UpperCase))
}
Certificate

一个证书文件可能包含多个Certificate,证书之间具有层级关系

通过上级证书可以颁发下级证书,这种关系叫做信任链

证书通过Certificate表示,证书信任链通过CertificatePath表示

可通过CertificateFactory来生成证书和证书信任链对象

val crtPath1 = "/home/easing/Temp/a.cer"
val crtPath2 = "/home/easing/Temp/b.cer"
val factory = CertificateFactory.getInstance("X.509")
val certificates1 = factory.generateCertificates(FileInputStream(crtPath1)).toList()
val certPath1 = factory.generateCertPath(certificates1)
val certificates2 = factory.generateCertificates(FileInputStream(crtPath2)).toList()
val certPath2 = factory.generateCertPath(certificates2)
KeyStore

秘钥库,用于保存秘钥和证书,比较常见的是JKS和PKCS12格式

可以理解为一个特殊格式的压缩包,可以设置密码,可以保存多份秘钥和证书

val keyStore = KeyStore.getInstance()
keyStore.load()
keyStore.store()
keyStore.size()
keyStore.aliases().toList()
keyStore.getCertificate()
keyStore.setKeyEntry()
keyStore.setCertificateEntry()
keyStore.getEntry()
keyStore.entryInstanceOf()
KeyStore.Entry

KeyStore通过别名,可以存储三种不同类型的数据

  • PrivateKeyEntry,私钥
  • SecretKeyEntry,对称秘钥
  • TrustedCertificateEntry,信任证书
MessageDiagest

消息摘要工具类

通过对一段完整数据,进行特定的运算,可以得到一串散列值

散列运算是不可逆的,且同样的数据,生成的散列值是固定的

这种算法叫做消息摘要算法,可以用来校验数据的完整性

import java.io.ByteArrayInputStream
import java.io.InputStream
import java.security.DigestInputStream
import java.security.MessageDigestfun main() {println(digestText("Hello World"))println(digestInputStream(ByteArrayInputStream("Hello World".encodeToByteArray())))
}@OptIn(ExperimentalStdlibApi::class)
fun digestText(content: String): String {val input = content.encodeToByteArray()val digest = MessageDigest.getInstance("SHA")digest.update(input)val output = digest.digest()val sha = output.toHexString(HexFormat.UpperCase)return sha
}@OptIn(ExperimentalStdlibApi::class)
fun digestInputStream(inputStream: InputStream): String {val digest = MessageDigest.getInstance("SHA")val digestInputStream = DigestInputStream(inputStream, digest)val buffer = ByteArray(512)var offset = 0while (true) {val read = digestInputStream.read(buffer, offset, 64)if (read <= 0) {break}offset += read}val output = digest.digest()digestInputStream.close()val sha = output.toHexString(HexFormat.UpperCase)return sha
}
Signature

签名工具类,用于私钥签名,或公钥校验

数据发送方对数据进行摘要,再通过私钥对摘要进行加密

数据接收方通过公钥对摘要进行解密,再对数据进行摘要,与解密出的摘要值进行对比,判断是否一致

这样既能保证发送方身份,也能保证数据完整性

fun generateKeyPair(): KeyPair {val generator = KeyPairGenerator.getInstance("DSA")generator.initialize(1024)val keyPair = generator.genKeyPair()return keyPair
}fun signAndVerify() {val keyPair = generateKeyPair()val data = "Hello World".encodeToByteArray()val signature = Signature.getInstance(keyPair.private.algorithm)// signsignature.initSign(keyPair.private)signature.update(data)val sign = signature.sign()// verifysignature.initVerify(keyPair.public)signature.update(data)val result = signature.verify(sign)println(result)
}
CodeSigner

用于封装签名信息,可用来对比两个签名是否一致

val date = Date()
val timestamp1 = Timestamp(date, certPath1)
val timestamp2 = Timestamp(date, certPath2)
val sign1 = CodeSigner(certPath1, timestamp1)
val sign2 = CodeSigner(certPath2, timestamp2)
println(sign1 == sign2)
SignedObject

SignedObject允许在内存中对数据进行签名和验证

SignedObject具有以下特点

  • 独立于真实数据,不可被中途篡改
  • 方便在代码中进行操作
  • 通过重写verify方法,可以实现自定义的签名验证逻辑
public SignedObject(Serializable object, PrivateKey signingKey, Signature signingEngine)public byte[] getSignature()public boolean verify(PublicKey verificationKey, Signature verificationEngine)
Cipher

Cipher是一个超级强大的加密解密类

  • 支持格式加密类型和加密算法

  • 支持通过Key或Certificate来加密解密

  • 支持Key的封包解包(Wrap/Unwrap)

Cipher对称加密解密
fun encryptAndDecrypt() {val shareKey = KeyGenerator.getInstance("DES").generateKey()val encryptKey = SecretKeySpec(shareKey.encoded, shareKey.algorithm)val decryptKey = SecretKeySpec(shareKey.encoded, shareKey.algorithm)// encrypt dataval cipher1 = Cipher.getInstance("DES")cipher1.init(Cipher.ENCRYPT_MODE, encryptKey)val encrypted = cipher1.doFinal("Hello World".encodeToByteArray())// decrypt dataval cipher2 = Cipher.getInstance("DES")cipher2.init(Cipher.DECRYPT_MODE, decryptKey)val decrypted = cipher2.doFinal(encrypted)println(decrypted.decodeToString())
}
Cipher非对称加密解密
fun encryptAndDecrypt() {val keyPair = KeyPairGenerator.getInstance("RSA").genKeyPair()val privateKeySpec = PKCS8EncodedKeySpec(keyPair.private.encoded)val publicKeySpec = X509EncodedKeySpec(keyPair.public.encoded)val privateKey = KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec)val publicKey = KeyFactory.getInstance("RSA").generatePublic(publicKeySpec)// encrypt dataval cipher1 = Cipher.getInstance("RSA")cipher1.init(Cipher.ENCRYPT_MODE, privateKey)val encrypted = cipher1.doFinal("Hello World".encodeToByteArray())// decrypt dataval cipher2 = Cipher.getInstance("RSA")cipher2.init(Cipher.DECRYPT_MODE, publicKey)val decrypted = cipher2.doFinal(encrypted)println(decrypted.decodeToString())
}
Cipher封包解包

Key的封包解包是指Key本身被其它Key所加密,发送前需要先加密,使用时需要先解密

比如下面的例子,双方通过对称秘钥,可以是DH算法生成的交换秘钥,来加密解密其它秘钥

甲方通过shareKey对secretKey1进行加密,乙方通过shareKey解密出secretKey2,这两个应当相等

fun wrapAndUnwrap() {val shareKey = KeyGenerator.getInstance("DES").generateKey()val wrapKey = SecretKeySpec(shareKey.encoded, shareKey.algorithm)val unwrapKey = SecretKeySpec(shareKey.encoded, shareKey.algorithm)// wrap keyval secretKey1 = KeyGenerator.getInstance("DES").generateKey()val cipher1 = Cipher.getInstance("DES")cipher1.init(Cipher.WRAP_MODE, wrapKey)val wrappedSecretKey = cipher1.wrap(secretKey1)// unwrap keyval cipher2 = Cipher.getInstance("DES")cipher2.init(Cipher.UNWRAP_MODE, unwrapKey)val secretKey2 = cipher2.unwrap(wrappedSecretKey, "DES", Cipher.SECRET_KEY)println(secretKey1 == secretKey2)
}
CipherInputStream和CipherOutputStream

对于较大的字节数据,不方便通过字节数组一次性读写的,可以通过Stream来操作

配合DataInputStream,可以很方便得读写加密解密后的字符串

SealedObject

用于在内存中,对可序列化的对象进行加密解密

这里我们通过apache的commons-lang库来实现对象的序列化和反序列化

api("org.apache.commons:commons-lang3:3.14.0")
fun encryptAndDecryptBySealedObject() {val keyPair = KeyPairGenerator.getInstance("RSA").genKeyPair()val privateKeySpec = PKCS8EncodedKeySpec(keyPair.private.encoded)val publicKeySpec = X509EncodedKeySpec(keyPair.public.encoded)val privateKey = KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec)val publicKey = KeyFactory.getInstance("RSA").generatePublic(publicKeySpec)// encrypt dataval cipher1 = Cipher.getInstance("RSA")cipher1.init(Cipher.ENCRYPT_MODE, privateKey)val sealedObject1 = SealedObject("Hello World", cipher1)val encrypted = SerializationUtils.serialize(sealedObject1)// decrypt dataval sealedObject2 = SerializationUtils.deserialize<SealedObject>(encrypted)val cipher2 = Cipher.getInstance("RSA")cipher2.init(Cipher.DECRYPT_MODE, publicKey)val decrypted = sealedObject2.getObject(cipher2)println(decrypted)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/34391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

B端产品竞品分析-总结版

B端竞品分析的难点 分析维度-业务逻辑复杂 B端产品与C端产品业务模型不同&#xff0c;B端产品主要以业务为导向&#xff0c;因此其业务流程与业务逻辑梳理起来也会较C端产品复杂的多&#xff0c;对于个人能力也有一定的要求&#xff0c;需要我们具备相关领域或行业专业知识。…

猫头虎分享已解决Bug:Array Index Out of Bounds Exception

&#x1f42f; 猫头虎分享已解决Bug&#xff1a;Array Index Out of Bounds Exception &#x1f42f; 摘要 大家好&#xff0c;我是猫头虎&#xff0c;今天我们要聊聊后端开发中经常遇到的一个问题&#xff1a;Array Index Out of Bounds Exception&#xff0c;即 java.lang.…

win10 修改远程桌面端口,在Win10上修改远程桌面端口的要怎么操作

在Windows 10上修改远程桌面端口是一个涉及系统配置的过程&#xff0c;这通常是为了增强安全性或满足特定网络环境的需要。 一、通过注册表编辑器修改远程桌面端口 1. 打开注册表编辑器&#xff1a; - 按下Win R组合键&#xff0c;打开“运行”对话框。 - 在“运行”对话框…

大模型揭秘:AI与CatGPT在实体识别中的创新应用

摘要 尽管大规模语言模型 (LLM) 在各种 NLP 任务上已经取得了 SOTA 性能&#xff0c;但它在 NER 上的性能仍然明显低于监督基线。这是由于 NER 和 LLMs 这两个任务之间的差距&#xff1a;前者本质上是序列标记任务&#xff0c;而后者是文本生成模型。在本文中&#xff0c;我们…

【大数据】—双均线策略(移动平均线)

声明&#xff1a;股市有风险&#xff0c;投资需谨慎&#xff01;本人没有系统学过金融知识&#xff0c;对股票有敬畏之心没有踏入其大门&#xff0c;今天用另外一种方法模拟炒股&#xff0c;后面的模拟的实战全部用同样的数据&#xff0c;最后比较哪种方法赚的钱多。 量化交易…

【对象的存储与比较】equals() 和 hashCode() 方法

1. Lombok的EqualsAndHashCode(callSuper true) 注解 这个注解用来自动生成equals()和hashCode()方法。其中&#xff0c;callSuper true表示在生成这些方法时&#xff0c;还会考虑到父类中的字段&#xff0c;确保子类实例在比较相等性时也能正确地包含父类的字段比较。 2. …

《2024云安全资源池 能力指南》

《2024云安全资源池 能力指南》这份报告不仅梳理了云安全资源池的发展历程,还深入探讨了其在当前云计算环境下的重要性和必要性。报告详细分析了云安全资源池的市场需求、技术架构、关键技术以及行业应用案例,为政企用户提供了全面的云安全解决方案。通过资料收集、问卷调研、企…

从0开始C++(六):模板与容器的使用详讲

目录 一、模板 函数模板 实例 类模板 实例 二、容器 标准模板类STL 容器的概念 数组&#xff08;array&#xff09; 向量 (vector) 列表 (list) 队列 (queue) 双端队列 (deque) 集合 (set) 映射 (map) 哈希集合 (unordered_set) 哈希映射 (unordered_map) 三…

Unity | Shader基础知识(番外:模型的制作流程)

目录 一、前言 二、模型的诞生 三、模型的表面 四、模型的贴图 五、上完材质的模型 六、材质的来源 七、作者的碎碎念 一、前言 up发现&#xff0c;初学程序&#xff0c;除非你是美术&#xff0c;模型出生&#xff0c;要不然对这些都是萌萌哒&#xff08;蒙蒙哒&#x…

从宏基因组中鉴定病毒序列(2)

Introduction 在环境微生物学和生态学研究中&#xff0c;宏基因组学&#xff08;Metagenomics&#xff09;技术的应用已经彻底改变了我们对微生物群落的理解。宏基因组学通过对环境样本中的全部遗传物质进行测序和分析&#xff0c;可以全面揭示微生物群落的组成、功能和相互作…

Modbus转Profibus网关在汽车行业的应用

一、前言 在当前汽车工业的快速发展中&#xff0c;汽车制造商正通过自动化技术实现生产的自动化&#xff0c;目的是提高生产效率和减少成本。Modbus转Profibus网关&#xff08;XD-MDPB100&#xff09;应用于汽车行业&#xff0c;主要体现在提升自动化水平、优化数据传输以及实…

刷题之小欧的平均数(卡码网)

小欧的平均数 这道题不看解析的话完全没有思路&#xff0c;连题目都没读明白&#xff0c;甚至看了评论答出来了还是不知道为什么&#xff0c;有知道的朋友可以教教我 #include<iostream> using namespace std;int main() {int x,y,z;cin>>x>>y>>z;//…

【机器学习 复习】第10章 聚类算法

一、概念 1.聚类 &#xff08;1&#xff09;是无监督学习&#xff0c;其实无监督学习就是无中生有&#xff0c;不给你标准答案&#xff08;标签啊啥的&#xff09;&#xff0c;然后让你自己来。 &#xff08;2&#xff09;聚类就是这样&#xff0c;让机器自己根据相似特征把相…

找出1000以内的所有的完数

完数的概念&#xff1a;完数&#xff08;Perfect Number&#xff09;是一个正整数&#xff0c;它等于除了它本身以外所有正因子之和。例如&#xff0c;6的因子有1、2、3和6&#xff0c;其中1236&#xff0c;所以6是一个完数。 #include <stdio.h> // 函数用于计算一个数…

怎么将图片压缩调小?在线压缩图片的4种快捷方法

压缩图片是日常很常用的一个图片处理功能&#xff0c;现在拍摄和制作的图片都比较大&#xff0c;在使用时经常会受到影响。在遇到无法上传、传输过慢的问题时会降低工作效率&#xff0c;所以掌握一招快速压缩图片是非常重要的。通过下面这篇文章来给大家介绍一下在线图片压缩的…

Flutter ffi Failed to lookup symbol

iOS release版本&#xff0c;解决方式参考官方文档&#xff1a;在 iOS 中使用 dart:ffi 调用本地代码 如果debug版本也报这个错误&#xff0c;很可能是有多个.c文件&#xff0c;编译的时候没带上&#xff01; 假设你的ffi模块名字是 c_lib 对于Android端&#xff0c;需要修改…

基于Pytorch框架构建AlexNet模型

Pytorch 一、判断环境1.导入必要的库2.判断环境 二、定义字典1.定义字典 三、处理图像数据集1.导入必要的模块2.定义变量3.删除隐藏文件/文件夹 四、加载数据集1.加载训练数据集2.加载测试数据集3.定义训练数据集和测试集路径4.加载训练集和测试集5.创建训练集和测试集数据加载…

Vue源码分析之Vue入口文件_vue打包后的入口文件是哪个

return n * n; } square(“2”); // Error! //添加类型注释&#xff0c;现在 Flow 就能检查出错误&#xff0c;因为函数参数的期待类型为数字&#xff0c;而我们提供了字符串。 #### 1.2 Vue.js源码目录###### Vue.js 的源码都在 src 目录下&#xff0c;其目录结构如下&#xf…

Vuex中的重要核心属性

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 Vuex 的核心属性包括&#xff1a; State: State 是 Vuex 存储数据的地方&#xff0c;类似于组件中的 data。它…

elementUI相关知识及搭建使用过程

​​​​​​ 目录 ​​​​​​ 一.elementUI相关的知识 1.什么是elementUI 2.如何在创建的项目中使用elementUI的组件(1)安装 ​ (2)在项目的main.js中引入elementUI (3)使用elementui里的组件 一.elementUI相关的知识 1.什么是elementUI Element&#xff0c;一套为开…