陪玩小程序源码,不容错过的加密算法整理清单

陪玩小程序源码,不容错过的加密算法整理清单

在开发陪玩小程序源码时,可采用的加密算法类型包含:

对称加密

对称加密算法,使用Cipher类即可,以广泛使用的AES为例,如下:

public byte[] encrypt(byte[] data, Key key) {try {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");byte[] iv = SecureRandoms.randBytes(cipher.getBlockSize());//初始化密钥与加密参数ivcipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));//加密byte[] encryptBytes = cipher.doFinal(data);//将iv与密文拼在一起ByteArrayOutputStream baos = new ByteArrayOutputStream(iv.length + encryptBytes.length);baos.write(iv);baos.write(encryptBytes);return baos.toByteArray();} catch (Exception e) {return ExceptionUtils.rethrow(e);}
}public byte[] decrypt(byte[] data, Key key) {try {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//获取密文前面的ivIvParameterSpec ivSpec = new IvParameterSpec(data, 0, cipher.getBlockSize());cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);//解密iv后面的密文return cipher.doFinal(data, cipher.getBlockSize(), data.length - cipher.getBlockSize());} catch (Exception e) {return ExceptionUtils.rethrow(e);}
}

 

如上,对称加密主要使用Cipher,不管是AES还是DES,Cipher.getInstance()传入不同的算法名称即可。
另外,为了使得每次加密出来的密文不同,我使用了随机的iv向量,并将iv向量拼接在了密文前面。

非对称加密

非对称加密同样是使用Cipher类,只是传入的密钥对象不同,以RSA算法为例,如下:

public byte[] encryptByPublicKey(byte[] data, PublicKey publicKey){try{Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}catch (Exception e) {throw Errors.toRuntimeException(e);}
}public byte[] decryptByPrivateKey(byte[] data, PrivateKey privateKey){try{Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}catch (Exception e) {throw Errors.toRuntimeException(e);}
}

 

一般来说应使用公钥加密,私钥解密,但其实反过来也是可以的。

密码学哈希

密码学哈希算法包括MD5、SHA1、SHA256等,在JCA中都使用MessageDigest类即可,如下:

public static String sha256(byte[] bytes) throws NoSuchAlgorithmException {MessageDigest digest = MessageDigest.getInstance("SHA-256");digest.update(bytes);return Hex.encodeHexString(digest.digest());
}

 

消息认证码

消息认证码使用Mac类实现,以常见的HMAC搭配SHA256为例,如下:

public byte[] digest(byte[] data, Key key) throws InvalidKeyException, NoSuchAlgorithmException{Mac mac = Mac.getInstance("HmacSHA256");mac.init(key);return mac.doFinal(data);
}

 

数字签名

数字签名使用Signature类实现,以RSA搭配SHA256为例,如下:

public byte[] sign(byte[] data, PrivateKey privateKey) {try {Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(privateKey);signature.update(data);return signature.sign();} catch (Exception e) {return ExceptionUtils.rethrow(e);}
}public boolean verify(byte[] data, PublicKey publicKey, byte[] sign) {try {Signature signature = Signature.getInstance("SHA256withRSA");signature.initVerify(publicKey);signature.update(data);return signature.verify(sign);} catch (Exception e) {return ExceptionUtils.rethrow(e);}
}

 

密钥协商算法

在JCA中,使用KeyAgreement来调用密钥协商算法,以ECDH协商算法为例,如下:

public static void testEcdh() {KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");keyGen.initialize(ecSpec);// A生成自己的私密信息KeyPair keyPairA = keyGen.generateKeyPair();KeyAgreement kaA = KeyAgreement.getInstance("ECDH");kaA.init(keyPairA.getPrivate());// B生成自己的私密信息KeyPair keyPairB = keyGen.generateKeyPair();KeyAgreement kaB = KeyAgreement.getInstance("ECDH");kaB.init(keyPairB.getPrivate());// B收到A发送过来的公用信息,计算出对称密钥kaB.doPhase(keyPairA.getPublic(), true);byte[] kBA = kaB.generateSecret();// A收到B发送过来的公开信息,计算对对称密钥kaA.doPhase(keyPairB.getPublic(), true);byte[] kAB = kaA.generateSecret();Assert.isTrue(Arrays.equals(kBA, kAB), "协商的对称密钥不一致");
}

 

基于口令加密PBE

通常,对称加密算法需要使用128位字节的密钥,但这么长的密钥用户是记不住的,用户容易记住的是口令,也即password,但与密钥相比,口令有如下弱点:

1、口令通常较短,这使得直接使用口令加密的强度较差。
2、口令随机性较差,因为用户一般使用较容易记住的东西来生成口令。

为了使得用户能直接使用口令加密,又能最大程度避免口令的弱点,于是PBE(Password Based Encryption)算法诞生,思路如下:

既然密码算法需要密钥,那在加解密前,先使用口令生成密钥,然后再使用此密钥去加解密。
为了弥补口令随机性较差的问题,生成密钥时使用随机盐来混淆口令来产生准密钥,再使用散列函数对准密钥进行多次散列迭代,以生成最终的密钥。
因此,使用PBE算法进行加解密时,除了要提供口令外,还需要提供随机盐(salt)与迭代次数(iteratorCount),如下:

public static byte[] encrypt(byte[] plainBytes, String password, byte[] salt, int iteratorCount) {try {PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES").generateSecret(keySpec);Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");cipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(salt, iteratorCount));byte[] encryptBytes = cipher.doFinal(plainBytes);byte[] iv = cipher.getIV();ByteArrayOutputStream baos = new ByteArrayOutputStream(iv.length + encryptBytes.length);baos.write(iv);baos.write(encryptBytes);return baos.toByteArray();} catch (Exception e) {throw Errors.toRuntimeException(e);}
}public static byte[] decrypt(byte[] secretBytes, String password, byte[] salt, int iteratorCount) {try {PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES").generateSecret(keySpec);Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");IvParameterSpec ivParameterSpec = new IvParameterSpec(secretBytes, 0, cipher.getBlockSize());cipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(salt, iteratorCount, ivParameterSpec));return cipher.doFinal(secretBytes, cipher.getBlockSize(), secretBytes.length - cipher.getBlockSize());} catch (Exception e) {throw Errors.toRuntimeException(e);}
}public static void main(String[] args) throws Exception {byte[] content = "hello".getBytes(StandardCharsets.UTF_8);byte[] salt = Base64.decode("QBadPOP6/JM=");String password = "password";byte[] encoded = encrypt(content, password, salt, 1000);System.out.println("密文:" + Base64.encode(encoded));byte[] plainBytes = decrypt(encoded, password, salt, 1000);System.out.println("明文:" + new String(plainBytes, StandardCharsets.UTF_8));
}

 

注意,虽然使用PBE加解密数据,都需要使用相同的password、salt、iteratorCount,但这里面只有password是需要保密的,salt与iteratorCount不需要,可以保存在数据库中,比如每个用户注册时给他生成一个随机盐。

到此,JCA密码算法就介绍完了,来回顾一下:

 

整体来说,JCA对密码算法相关的类设计与封装还是非常清晰简单的!

以上就是陪玩小程序源码,不容错过的加密算法整理清单, 更多内容欢迎关注之后的文章

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

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

相关文章

【QT】工程库引用

创建多工程项目创建子项目UI窗体项目创建库工程项目引用库工程添加日志输出类5.1 需要添加特殊配置,否则编译会报错5.2 正确添加配置5.3 日志正常输出5.4 如果缺少5.1步骤,则报如下错误5.5 如果添加了5.1步骤,还是报The process was ended forcefully 找到项目文件,把debug…

陪玩系统源码,为守护系统安全增添更多助力

陪玩系统源码,为守护系统安全增添更多助力在开发陪玩系统源码时,可以通过加密、解密算法来提升系统的安全性,比较常见的加密、解密算法类型有:1、对称加密:速度快,可逆,常见DES,AES等2、非对称加密:速度慢,可逆,常见RSA等3、签名算法:唯一,不可逆,常见MD5,SHA,…

pycharm创建临时文件scatch file

JetBrains PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。 有时您可能需要创建临时注释或在项目上下文之外起草一些代码。为此,您可以使用临时文件和临时缓冲…

P5441

P5441 神仙题目。 tips:后面把 \(4\) 个点说成一个组。我们先考虑一个组怎么连才不是强联通的。一个点 A 向另外三个点 BCD 连一条有向边。在不满足第一种的情况下,BCD 向另一个点 A 连一条有向边。AB 之间连有向边,CD 之间连无向边,然后 AC 和 AD 连一条有向边,BC 和 BD …

二水中分白鹭洲

二水中分白鹭洲 题目大意 假设水中 \(n\) 条体积相等的鱼将按顺序依次排列,准备进行战斗。初始时,每条鱼可以选择向左游或向右游;但是鱼儿不太聪明,它们只会随机选择初始方向。 战斗时,若两条不同方向的鱼相遇,则体积大的鱼会吃掉体积小的鱼;如果两条鱼的体积相同,则向…

git恢复到之前提交的记录

项目搞崩了,还提交上去了怎么办? 那当然是恢复到之前的提交记录了,那怎么操作呢? 首先,到代码托管平台找到你想恢复的提交记录(在此以github为例) 获取 commit id 首先,通过如下图操作获取到commit id {% asset_img image-20240706062921362.png "..." "…

[python]Markdown图片引用格式批处理桌面应用程序

需求 使用python编写一个exe,实现批量修改图片引用,将修改后的文件生成为 文件名_blog.md。有一个编辑框,允许接收拖动过来md文件,拖入文件时获取文件路径,有一个编辑框编辑修改后的文件的输出路径,用户拖入文件时,就能自动得到输出的路径 作用是将md文件中的例如 ![ima…

读人工智能全传04NP完全问题

读人工智能全传04NP完全问题1. 问题解决与搜索 1.1. 解决问题的能力无疑是区分人类和其他动物的关键能力之一 1.1.1. 解决问题是需要智慧的 1.2. 汉诺塔 1.2.1. 对于三个金环而言 1.2.1.1. 你不可能找到少于7次的解决方案了 1.2.2. 最初,我们只能选择移动最小的金环,只有将它…

sunny 拦截不成功解决

可能开了tz,导致无法拦截请求 解决方法:打开这个注释本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18286840

02.内建变量类型

内建变量类型bool,string(u)int,(u)int8,(u)int16,(u)int32,(u)int64,uintptr 无长度 int 的实际长度取决于操作系统位数(32/64)uintptr 为指针类型byte,rune rune 为 Go 语言的字符型相当于其他语言的 char ,长度为4字节 int32float32,float32,complex64,complex128 complex …

01.变量定义

变量定义 新建项目func variableZeroValue() {//赋空值var a intvar s stringfmt.Printf("%d %q\n", a, s) } 变量赋空值func variableZeroValue() {//赋空值var a intvar s stringfmt.Printf("%d %q\n", a, s) } 变量赋初值func variableInitialValue()…

7.5 - 贪心篇完结

435. 无重叠区间 题意描述:[!WARNING] 给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。 示例 1: 输入: intervals = [[1,2],[2,3],[3,4],[1,3]] 输出: 1 解释: 移除 [1,3] 后,剩下的区间没有重叠。…