md5

md5是一种散列算法,不可逆,是一种消息摘要算法,生成的字节数组的长度是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中,通常为了便于输出,我们会将每个字节转变为16进制字符串,每个16进制都是2个字符,所以md5转化之后的字符是32个字符。

这里有个技术点需要注意的是,在对每个字节进行转化为16进制的字符串的 时候,0-15这几个值的字节,转化为的字符串的长度都是1,所以需要在前面补0

jdk原生md5

/*** jdk原生md5*/public static void md5() throws Exception {String str = "hello聚合";String algorithm = "MD5";MessageDigest instance = MessageDigest.getInstance(algorithm);byte[] digest = instance.digest(str.getBytes(StandardCharsets.UTF_8));System.out.println(new String(digest));//如果直接输出的话,是乱码�G�s�.u�Iz�۲�//这是因为md5生成的消息摘要是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中的//通常为了便于输出,我们会将每个字节转变为16进制字符串,每个16进制都是2个字符,所以md5转化之后的字符是32个字符StringBuilder stringBuilder = new StringBuilder();for (byte b : digest) {//每个字节转与0xff(1111 1111)按位与,得到这个字节的补码String hex = Integer.toHexString(b & 0xff);//如果生成的16进制的字符的长度是1,那么需要在前面补0,比如//0,5,10,13,15的16进制分别是是0,5,a,d,f,长度只有1,所以需要前面补0if (hex.length() == 1) {hex = "0" + hex;}stringBuilder.append(hex);}System.out.println(stringBuilder);}
}

使用commons-codec

需要引入jar包

<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version></dependency>
/*** 使用commons-codec*/public static void md5codec() {String str = "hello聚合";String encode = DigestUtils.md5Hex(str.getBytes(StandardCharsets.UTF_8));System.out.println(encode);}

全部代码

package codec.md5;import org.apache.commons.codec.digest.DigestUtils;import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;/*** @author micro.cloud.fly* @date 2021/8/30 11:28 上午* @desc md5消息摘要算法学习笔记*/
public class Demo1 {public static void main(String[] args) throws Exception {md5();System.out.println();md5codec();}/*** jdk原生md5*/public static void md5() throws Exception {String str = "hello聚合";String algorithm = "MD5";MessageDigest instance = MessageDigest.getInstance(algorithm);byte[] digest = instance.digest(str.getBytes(StandardCharsets.UTF_8));System.out.println(new String(digest));//如果直接输出的话,是乱码�G�s�.u�Iz�۲�//这是因为md5生成的消息摘要是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中的//通常为了便于输出,我们会将每个字节转变为16进制字符串,每个16进制都是2个字符,所以md5转化之后的字符是32个字符StringBuilder stringBuilder = new StringBuilder();for (byte b : digest) {//每个字节转与0xff(1111 1111)按位与,得到这个字节的补码String hex = Integer.toHexString(b & 0xff);//如果生成的16进制的字符的长度是1,那么需要在前面补0,比如//0,5,10,13,15的16进制分别是是0,5,a,d,f,长度只有1,所以需要前面补0if (hex.length() == 1) {hex = "0" + hex;}stringBuilder.append(hex);}System.out.println(stringBuilder);}/*** 使用commons-codec*/public static void md5codec() {String str = "hello聚合";String encode = DigestUtils.md5Hex(str.getBytes(StandardCharsets.UTF_8));System.out.println(encode);}
}

SHA-256

sha-256和md5一样,都是消息摘要算法,只不过是摘要后的长度是256位,也就是32个字节,同理,在转化为16进制的字符串之后,是64个字节,实现了md5之后,只要把算法algorithm改为SHA-256即可,以下是全部的代码

全部代码

package codec.sha256;import org.apache.commons.codec.digest.DigestUtils;import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;/*** @author micro.cloud.fly* @date 2021/8/30 11:28 上午* @desc sha256消息摘要算法学习笔记*/
public class Demo {public static void main(String[] args) throws Exception {md5();System.out.println();md5codec();}/*** jdk原生md5*/public static void md5() throws Exception {String str = "hello聚合";String algorithm = "SHA-256";MessageDigest instance = MessageDigest.getInstance(algorithm);byte[] digest = instance.digest(str.getBytes(StandardCharsets.UTF_8));System.out.println(new String(digest));//如果直接输出的话,是乱码�G�s�.u�Iz�۲�//这是因为md5生成的消息摘要是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中的//通常为了便于输出,我们会将每个字节转变为16进制字符串,每个16进制都是2个字符,所以md5转化之后的字符是32个字符StringBuilder stringBuilder = new StringBuilder();for (byte b : digest) {//每个字节转与0xff(1111 1111)按位与,得到这个字节的补码String hex = Integer.toHexString(b & 0xff);//如果生成的16进制的字符的长度是1,那么需要在前面补0,比如//0,5,10,13,15的16进制分别是是0,5,a,d,f,长度只有1,所以需要前面补0if (hex.length() == 1) {hex = "0" + hex;}stringBuilder.append(hex);}System.out.println(stringBuilder);}/*** 使用commons-codec*/public static void md5codec() {String str = "hello聚合";String encode = DigestUtils.sha256Hex(str.getBytes(StandardCharsets.UTF_8));System.out.println(encode);}
}

SHA-512

同sha-256原理一样,只要把algorithm算法名改为sha-512即可,以下是全部代码

package codec.sha512;import org.apache.commons.codec.digest.DigestUtils;import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;/*** @author micro.cloud.fly* @date 2021/8/30 11:28 上午* @desc sha512消息摘要算法学习笔记*/
public class Demo {public static void main(String[] args) throws Exception {md5();System.out.println();md5codec();}/*** jdk原生*/public static void md5() throws Exception {String str = "hello聚合";String algorithm = "SHA-512";MessageDigest instance = MessageDigest.getInstance(algorithm);byte[] digest = instance.digest(str.getBytes(StandardCharsets.UTF_8));System.out.println(new String(digest));//如果直接输出的话,是乱码�G�s�.u�Iz�۲�//这是因为md5生成的消息摘要是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中的//通常为了便于输出,我们会将每个字节转变为16进制字符串,每个16进制都是2个字符,所以md5转化之后的字符是32个字符StringBuilder stringBuilder = new StringBuilder();for (byte b : digest) {//每个字节转与0xff(1111 1111)按位与,得到这个字节的补码String hex = Integer.toHexString(b & 0xff);//如果生成的16进制的字符的长度是1,那么需要在前面补0,比如//0,5,10,13,15的16进制分别是是0,5,a,d,f,长度只有1,所以需要前面补0if (hex.length() == 1) {hex = "0" + hex;}stringBuilder.append(hex);}System.out.println(stringBuilder);}/*** 使用commons-codec*/public static void md5codec() {String str = "hello聚合";String encode = DigestUtils.sha512Hex(str.getBytes(StandardCharsets.UTF_8));System.out.println(encode);}
}

MAC

mac也是一种消息摘要,同md5、SHA256算法不同的是,它在进行消息摘要的时候,需要一个key,相同于密钥,mac算法有macMD5、macSHA256、macSHA512等多种,在实现的时候,也是只需要改一个算法名称即可,以下是实现的全部代码

package codec.lesson05_mac;import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;/*** @author micro.cloud.fly* @date 2021/8/30 11:28 上午* @desc mac消息摘要算法学习笔记*/
public class Demo1 {public static void main(String[] args) throws Exception {mac();System.out.println();maccodec();}/*** jdk原生md5*/public static void mac() throws Exception {String str = "hello聚合";String key = "123";String algorithm = "HmacMD5";//使用其他算法,只需要改一下名字即可algorithm = "HmacSHA256";algorithm = "HmacSHA512";//实例化mac对象Mac mac = Mac.getInstance(algorithm);//实例化key对象SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);//mac对象初始化mac.init(secretKeySpec);byte[] bytes = mac.doFinal(str.getBytes(StandardCharsets.UTF_8));StringBuilder stringBuilder = new StringBuilder();for (byte b : bytes) {//每个字节转与0xff(1111 1111)按位与,得到这个字节的补码String hex = Integer.toHexString(b & 0xff);//如果生成的16进制的字符的长度是1,那么需要在前面补0,比如//0,5,10,13,15的16进制分别是是0,5,a,d,f,长度只有1,所以需要前面补0if (hex.length() == 1) {hex = "0" + hex;}stringBuilder.append(hex);}System.out.println(stringBuilder);}/*** 使用commons-codec*/public static void maccodec() {String str = "hello聚合";String key = "123";System.out.println("hmacMD5:"+new HmacUtils(HmacAlgorithms.HMAC_MD5, key.getBytes(StandardCharsets.UTF_8)).hmacHex(str.getBytes(StandardCharsets.UTF_8)));System.out.println("hmacSHA256:"+new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key.getBytes(StandardCharsets.UTF_8)).hmacHex(str.getBytes(StandardCharsets.UTF_8)));System.out.println("hmacSHA512:"+new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key.getBytes(StandardCharsets.UTF_8)).hmacHex(str.getBytes(StandardCharsets.UTF_8)));}
}

DES

des是一种对称加密算法,相对于非对称加密算法来说,更快,现在des已经过时,被AES给取代了,需要注意的是,des算法的时候,key必须是8个字节,不然会报错。以下是使用des加密解密的全部代码。

package codec;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** @author micro.cloud.fly* @date 2021/8/30 2:04 下午* @desc 学习des算法,des是对称加密,比起非对称加密,有点是更快,因为只使用一个key*/
public class lesson06_DES {public static void main(String[] args) throws Exception {String encryptedString = encrypt();String decryptedString = decrypt(encryptedString);System.out.println(decryptedString);}private static String decrypt(String encryptedString) throws Exception {String algorithm = "DES";Cipher cipher = Cipher.getInstance(algorithm);String key = "12345678";//这里必须是8个字节SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);//传参过来的明文,是base64编码后的内容,所以,需要先进行base64解码byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(encryptedString.getBytes(StandardCharsets.UTF_8)));return new String(bytes, StandardCharsets.UTF_8);}/*** 使用DES加密** @return 加密后的内容*/public static String encrypt() throws Exception {String algorithm = "DES";String str = "hello聚合";//cipher是密码的意思,这里是实例化一个cipher对象,//这里ECB是指加密的模式,是java的默认加密模式,PKCS7Padding是指填充模式,加密模式和填充模式也可以不进行指定Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");String key = "12345678";//这里必须是8个字节//实例化一个密钥,第一个参数是密钥,第二个参数是算法SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);//cipher初始化,第一个参数是加解密模式,即,cipher是为了加密,还是用来解密,第二个参数是密钥对象cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));//得到的是字节数组,通常的做法是把此处的字节数组转为base64进行展示byte[] encode = Base64.getEncoder().encode(bytes);System.out.println(new String(encode, StandardCharsets.UTF_8));return new String(encode);}
}

AES

aes和des差不多,只需要改algorithm的名字即可,不同点是,aes的key的长度必须是16、24、32个字节,不过可以通过key generator进行优化,优化后可以使用任意的长度的key,当使用填充模式为NoPadding的方式时,des的key必须为8个字节,aes的key必须是16,24,32个字节。
ECB:java默认的 加密模式,是指把明文分组之后,每个组进行并行加密,然后拼接,所以效率会比较高
CBC:采用的是将明文进行分组,后面分组的内容加密时,依赖前一个分组加密后的密文,也就是每次加密后的密文,后面的组进行加密的时候,都根据这个密文与后面的组的明文进行一起加密,这种模式下,需要一个initialization vector,简称IV,即初始化向量,这个初始化向量默认必须是16个字节。
以下是完整的代码展示

package codec.lesson07_AES;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;/*** @author micro.cloud.fly* @date 2021/8/30 2:04 下午* @desc 学习aes算法,aes是对称加密,比起非对称加密,有点是更快,因为只使用一个key*/
public class Demo02 {public static void main(String[] args) throws Exception {//常规加密String encryptedString = encrypt();//常规解密String decryptedString = decrypt(encryptedString);System.out.println(decryptedString);System.out.println();//优化后的加密String s = encryptOptimise();//优化后的解密String s1 = decryptOptimise(s);System.out.println(s1);}/*** 使用AES加密** @return 加密后的内容*/public static String encrypt() throws Exception {String algorithm = "AES";String str = "hello聚合";//cipher是密码的意思,这里是实例化一个cipher对象,//这里ECB是指加密的模式,是java的默认加密模式,// PKCS5Padding是指填充模式,也是java默认的填充方式,Cipher cipher = Cipher.getInstance(algorithm);//这里与des区别的地方是,des必须是8个字节,而aes必须是16,24,32个字节/*在接口AESConstants中明确规定了长度interface AESConstants {int AES_BLOCK_SIZE = 16;int[] AES_KEYSIZES = new int[]{16, 24, 32};}*/String key = "1234567812345678";//实例化一个密钥,第一个参数是密钥,第二个参数是算法SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);//cipher初始化,第一个参数是加解密模式,即,cipher是为了加密,还是用来解密,第二个参数是密钥对象//默认的是ECB加密模式,如果使用的CBC模式的话,需要多传一个IV向量,即initialization vectorString iv = "12345678abcdabcd";IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);//CBC模式下,必须有第三个参数IV//cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,ivParameterSpec);byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));//得到的是字节数组,通常的做法是把此处的字节数组转为base64进行展示byte[] encode = Base64.getEncoder().encode(bytes);System.out.println(new String(encode, StandardCharsets.UTF_8));return new String(encode);}private static String decrypt(String encryptedString) throws Exception {String algorithm = "AES";Cipher cipher = Cipher.getInstance(algorithm);String key = "1234567812345678";//这里必须是8个字节SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);//传参过来的明文,是base64编码后的内容,所以,需要先进行base64解码byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(encryptedString.getBytes(StandardCharsets.UTF_8)));return new String(bytes, StandardCharsets.UTF_8);}/*** 优化后的aes加密算法,这是因为默认key的长度只能是16, 24, 32个字节,此处使用key工厂,可以传递任意字节的密钥** @return 加密后的内容*/public static String encryptOptimise() throws Exception {String algorithm = "AES";String str = "hello聚合";//cipher是密码的意思,这里是实例化一个cipher对象,Cipher cipher = Cipher.getInstance(algorithm);//实例化key工厂KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);//初始化secureRandom,并指定生成key的算法SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");String key = "1234567812345";//设置key工厂的种子secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8));//第一个参数是生成原始key的长度,第二个参数是SecureRandom对象keyGenerator.init(128, secureRandom);SecretKey secretKey = keyGenerator.generateKey();//获取到新的密钥的字节数组byte[] encodedKey = secretKey.getEncoded();//实例化一个密钥,第一个参数是密钥,第二个参数是算法SecretKeySpec secretKeySpec = new SecretKeySpec(encodedKey, algorithm);//cipher初始化,第一个参数是加解密模式,即,cipher是为了加密,还是用来解密,第二个参数是密钥对象cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));//得到的是字节数组,通常的做法是把此处的字节数组转为base64进行展示byte[] encode = Base64.getEncoder().encode(bytes);System.out.println(new String(encode, StandardCharsets.UTF_8));return new String(encode);}/*** 优化后的aes解密算法,这是因为默认key的长度只能是16, 24, 32个字节,此处使用key工厂,可以传递任意字节的密钥** @return 加密后的内容*/public static String decryptOptimise(String encryptStr) throws Exception {String algorithm = "AES";//cipher是密码的意思,这里是实例化一个cipher对象,Cipher cipher = Cipher.getInstance(algorithm);//实例化key工厂KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);//初始化secureRandom,并指定生成key的算法SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");String key = "1234567812345";//设置key工厂的种子secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8));//第一个参数是生成原始key的长度,第二个参数是SecureRandom对象keyGenerator.init(128, secureRandom);SecretKey secretKey = keyGenerator.generateKey();//获取到新的密钥的字节数组byte[] encodedKey = secretKey.getEncoded();//实例化一个密钥,第一个参数是密钥,第二个参数是算法SecretKeySpec secretKeySpec = new SecretKeySpec(encodedKey, algorithm);//cipher初始化,第一个参数是加解密模式,即,cipher是为了加密,还是用来解密,第二个参数是密钥对象cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(encryptStr.getBytes(StandardCharsets.UTF_8)));return new String(bytes);}
}

RSA 非对称加密算法

简介:

① 非对称加密算法又称现代加密算法。

② 非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。

③ 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey) 和私有密(privatekey)

④ 公开密钥和私有密钥是一对

⑤ 如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。

⑥ 如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。

⑦ 因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

原理示例

首先生成密钥对, 公钥为(5,14), 私钥为(11,14)
现在A希望将原文2发送给B
A使用公钥加密数据. 2的5次方mod 14 = 4 , 将密文4发送给B
B使用私钥解密数据. 4的11次方mod14 = 2, 得到原文2
特点
加密和解密使用不同的密钥
如果使用私钥加密, 只能使用公钥解密
如果使用公钥加密, 只能使用私钥解密
处理数据的速度较慢, 因为安全级别高

常见算法

  • RSA
  • ECC

数字签名

带数字签名的非对称加密算法

 package codec.lesson08_RSA;import org.apache.commons.io.FileUtils;import javax.crypto.Cipher;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;/*** @author micro.cloud.fly* @date 2021/8/31 11:33 上午* @desc RSA 加密的测试用例*/
public class RSACodeCUtil {public static String PUB_PATH;public static String PRI_PATH;public static void main(String[] args) throws Exception {//                writeKeyPair2LocalFile();//这里需要格外注意的是,加密的数据长度不能超过117个字节,解密的数据的长度不能超过128个字节,如果超过了,需要分段进行处理String str = "你好聚合数据你好聚合数据你好聚合jjjjj数据你好聚合数据你好聚合数据你好聚合数据你好聚合数据你好聚合数据你好聚合数据你好聚合数据";
//        str = "anhui";String encryptStr = encrypt(str);
//                String encryptStr = encrypt("安徽");System.out.println("加密后的数据是:" + encryptStr);String decrypt = decrypt(encryptStr);System.out.println("解密后的数据为:" + decrypt);String sign = sign(str);System.out.println("得到的签名数据是:" + sign);boolean verify = verify(str, sign);System.out.println("签名的验证结果是:" + verify);}/*** 消息签名** @param data 原始消息内容* @return 消息签名*/public static String sign(String data) throws Exception {Signature signature = Signature.getInstance("sha256withrsa");signature.initSign(getPrivateKey());signature.update(data.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(signature.sign());}/*** 验证签名* @param data 原始数据* @param sign 签名内容* @return 签名是否验证成功*/public static boolean verify(String data, String sign) throws Exception {//给过来的签名是base64编码过的,所以此处需要base64进行解码byte[] bytes = Base64.getDecoder().decode(sign.getBytes(StandardCharsets.UTF_8));Signature signature = Signature.getInstance("sha256withrsa");signature.initVerify(getPublicKey());signature.update(data.getBytes(StandardCharsets.UTF_8));return signature.verify(bytes);}/*** 加密** @param input 待加密的字符串* @return 加密内容*/public static String encrypt(String input) throws Exception {Cipher cipher = Cipher.getInstance("RSA");//第一个参数:加密模式//第二个参数:使用公钥加密还是私钥加密,此处使用的是公钥cipher.init(Cipher.ENCRYPT_MODE, getPublicKey());byte[] inputArray = input.getBytes();int inputLength = inputArray.length;System.out.println("加密字节数:" + inputLength);// 最大加密字节数,超出最大字节数需要分组加密int MAX_ENCRYPT_BLOCK = 117;// 标识int offSet = 0;byte[] resultBytes = {};byte[] cache;while (inputLength - offSet > 0) {if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);offSet += MAX_ENCRYPT_BLOCK;} else {cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);offSet = inputLength;}resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);}return Base64.getEncoder().encodeToString(resultBytes);}/*** 解密* @param encryptStr 被加密过的base64编码过的密文* @return 原始内容*/public static String decrypt(String encryptStr) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());byte[] decode = Base64.getDecoder().decode(encryptStr);//设置每个块的容量是128个字节int blockSize = 128;int currentPosition = 0;int totalSize = decode.length;byte[] result = {};byte[] bytes;while (totalSize - currentPosition > 0) {//如果总长度减去当前位置大于0,则一直循环下去if (totalSize - currentPosition > blockSize) {bytes = cipher.doFinal(decode, currentPosition, blockSize);currentPosition += blockSize;} else {bytes = cipher.doFinal(decode, currentPosition, totalSize - currentPosition);currentPosition = totalSize;}//result扩容result = Arrays.copyOf(result, result.length + bytes.length);//把每次读取的内容,写到扩容后的数组中System.arraycopy(bytes, 0, result, result.length - bytes.length, bytes.length);}return new String(result, StandardCharsets.UTF_8);}static {PUB_PATH = RSACodeCUtil.class.getClassLoader().getResource("rsa.pub").getPath();PRI_PATH = RSACodeCUtil.class.getClassLoader().getResource("rsa.pri").getPath();}/*** 生成密钥对,并且编码为base64,然后写入到文件**/public static void writeKeyPair2LocalFile() throws Exception {//密钥对生成器对象KeyPairGenerator keypairgenerator = KeyPairGenerator.getInstance("RSA");//设置密钥对长度keypairgenerator.initialize(1024);//生成密钥对KeyPair keyPair = keypairgenerator.generateKeyPair();//获取私钥对象PrivateKey aPrivate = keyPair.getPrivate();//获取公钥对象PublicKey aPublic = keyPair.getPublic();//经对象转为base64编码String encodePrivate = Base64.getEncoder().encodeToString(aPrivate.getEncoded());String encodePublic = Base64.getEncoder().encodeToString(aPublic.getEncoded());//写入到文件FileUtils.writeStringToFile(new File(PUB_PATH), encodePublic, StandardCharsets.UTF_8);FileUtils.writeStringToFile(new File(PRI_PATH), encodePrivate, StandardCharsets.UTF_8);}/*** 获取公钥** @return* @throws Exception*/public static PublicKey getPublicKey() throws Exception {//从文件中加载已经base64编码过的公钥String base64EncodedPublicKey = FileUtils.readFileToString(new File(PUB_PATH), StandardCharsets.UTF_8);//base64解码byte[] decodeKey = Base64.getDecoder().decode(base64EncodedPublicKey.getBytes(StandardCharsets.UTF_8));//对于公钥来说,规则是x509KeyFactory keyFactory = KeyFactory.getInstance("RSA");KeySpec keySpec = new X509EncodedKeySpec(decodeKey);return keyFactory.generatePublic(keySpec);}public static PrivateKey getPrivateKey() throws Exception {//从文件中加载已经base64编码过的公钥String base64EncodedPrivateKey = FileUtils.readFileToString(new File(PRI_PATH), StandardCharsets.UTF_8);//base64解码byte[] decodeKey = Base64.getDecoder().decode(base64EncodedPrivateKey.getBytes(StandardCharsets.UTF_8));//对于私钥来说,规则是pkcs8KeyFactory keyFactory = KeyFactory.getInstance("RSA");KeySpec keySpec = new PKCS8EncodedKeySpec(decodeKey);return keyFactory.generatePrivate(keySpec);}
}```

java编码解码加密解密--md5、SHA-256、SHA-512、MAC、DES、AES、RSA相关推荐

  1. 安全篇 ━━ JWT的用途和安全探讨,编码解码=\=加密解密

    一.定义 JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred betw ...

  2. Vue项目:路由跳转时中文传参被URL编码,怎么解决?用js封装Base64编码解码加密解密

    1.在utils中封装js方法,代码如下: var Base64 = { ​// private property_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZab ...

  3. Java常见的加密解密

    Java常见的加密解密 不可逆加密 介绍 应用场景 一致性验证 MD5 可以为文件传输场景中,提供文件的一致性验证. 例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法 ...

  4. Java实现3DES加密解密(DESede/ECB/PKCS5Padding使用)

    一.简介 3DES(又叫Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称. 它相当于是对每个数据块应用三次DES加密算 ...

  5. java 文件进行加密解密,java 对文件加密解密,该如何解决

    java 对文件加密解密 本帖最后由 Hong_1993 于 2014-09-03 10:51:35 编辑 我现在想做一个基于spring mvc 模式的 实现对  文件或目录文件   的加解密(de ...

  6. js编码java解码_常用的js、java编码解码方法

    前言 前后端直接传输数据进行交互不就行了吗,为什么还要进行编码解码?正常情况下直接交互没问题,但当有类似以下情况出现时就需要进行编码再进行传输: 1.编码格式难以统一,导致数据交互过程出现中文乱码等问 ...

  7. java 3des_如何用Java进行3DES加密解密 java实现3des加密解密教程

    3des,全称为3DESede或TripleDES,中文解释为是三重数据加密,用户可以通过通过对DES算法进行改进,针对每个数据块进行三次DES加密,下面小编为你带来java实现3des加密解密教程! ...

  8. 加密算法(DES,AES,RSA,ECC,MD5,SHA1)简介

    加密算法(DES,AES,RSA,MD5,SHA1)简介 一.对称性加密算法 二.非对称算法 三.散列算法 四.算法举例 1.对称性加密算法有:AES.DES.3DES 1.1.DES(Data En ...

  9. 用java实现3DES加密解密算法

    3DES加密也称三重加密,其底层加密算法与DES相同,只不过它的密钥长度是168位.由于在DES加密算法中,64位密钥中每一个字节的第8位是奇偶校验位,所以每个字节中只有后7位起密钥作用,实际是56位 ...

最新文章

  1. IDEA 13 tomcat 进行远程调试
  2. 果蝇玩VR登Nature,发现注意力机制、工作记忆都有,昆虫大脑原来没比哺乳类差多少...
  3. RecyclerView点击事件监听
  4. ubuntu java8 java9_在Ubuntu/Debian系统上安装Java 9的方法
  5. go如何进行交叉编译
  6. 使用jieba提取文本TF-IDF关键词
  7. 海量数据挖掘MMDS week2: Association Rules关联规则与频繁项集挖掘
  8. H5 设备运动事件 DeviceMotionEvent
  9. 众信金融获“2015最佳绿色贡献奖”
  10. 网站关键词-网站关键词设置方法-网站关键词排名优化软件
  11. html 字体样式及结果,css font-family 的种类、安全字体及写法(附样式图)
  12. LeetCode初级算法笔记整理
  13. 程序员入门:三本必看的书
  14. 开源,多用户分销微信商城源码分享
  15. java中类加载器ClassLoader,双亲加载机制,启动类加载器,应用类加载器,线程上下文类加载器
  16. DataStream与DataSet
  17. springboot+shiro自定义拦截器互踢问题
  18. 俞军:用户不是人,是需求的集合
  19. linux下远程桌面客户端Remmina
  20. go 语言下的go mod 问题

热门文章

  1. jQuery封装ajax
  2. 最新JS判断是否是360浏览器方法
  3. 无线牵起多个网络—美的无线网络解决方案
  4. 手机适配之 dimen 基础知识
  5. Python 学习系列(4) 在Python中建立N维数组并赋初值
  6. Swagger UI引入
  7. CMD命令跳转指定目录
  8. 华三交换机修改管理员密码命令
  9. Win11运行cmd提示“请求的操作需要提升”的解决方法
  10. jasonencode php_PHP的json_encode()函数与JSON对象