安全系列之——手写JAVA加密、解密

Java中使用Hutool进行AES加密解密详解 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式编程的简洁性。Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当。Hutool作为一款实用的Java工具类库,为开发者提供了简洁易用的AES加密解密API。 阅读详情

软件的加密与解密是一个迷人的研究领域,它几乎可以与任意一种计算机技术紧密结合——密码学、程序设计语言、操作系统、数据结构。而由于这样或者那样的原因,对于这一领域的关注程度一直还处于低温状态。

网络安全一般需要注意以下几个关键点:

  • 完整性(Integrity):确保信息在传输过程中,没有被篡改。* 私密性(Confidentiality):也就是通过加密,确保只有可信的实体可以看到这些信息。* 源认证(Authenticity):确保是可信的源发送了这些信息,而不是伪装源发送的消息。* 不可否认性(Nonrepudiation):不能事后否认发送过这条信息。今天我们说的是数据传输的私密性。加密技术是最常用的安全保密手段,利用技术手段把重要的数据变为乱码(加密)传送,到达目的地后再用相同或不同的手段还原(解密)。

加密技术包括两个元素:算法和密钥。

一、使用异或加密解密

先来看一个简单的加密解密的实例。

package com.wuxiaolong.EncrypteDecrypt;
import org.apache.commons.codec.digest.DigestUtils;

/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-07-22
 */
public class Test1 {public static void main(String[] args) {String content = "我爱你";Integer key = 1000;// 用户A发消息前,通过某种方式加密String encryptStr = xor(content,key);System.out.println(encryptStr);// 密文通过网络传输// 用户B收到密文后使用相同的方式解密String decryptStr = xor(encryptStr,key);System.out.println(decryptStr);}/** * 加密算法及秘钥 * @param content * @return */public static Stringxor(String content, Integer key){char[] chars = content.toCharArray();for(int i=0; i<chars.length; i++){chars[i] = (char)(chars[i]^key) ;}return new String(chars);}
} 

这里自定义了一个加解密方法xor,这个方法接收两个参数,一个是原文content,一个秘钥key。这样有加密算法,有秘钥,就可以加密了。

运行的结果:

懹燙䲈// 加密结果
我爱你// 解密结果 

二、异或加密解密原理讲解

在发消息前,需要使用算法+秘钥对传输的消息(明文)进行加密,加密后使用密文在网络传输,传输到目的地时,再使用相同的算法+秘钥将密文翻译成明文。

在这个加密和解密的过程中,使用了相同的算法+秘钥。

这里可以看出,一个明文连续使用相同的算法+秘钥做两次加密,就可以得到原来的明文了。

这和计算机中的异或运算(^)很像,异或英文为exclusive OR,缩写成xor,异或运行有两个特点:

  • 两个二进制数字相同为0,不同为1。* 一个数字两次异或后,得到的是原数字本身。下面使用一个字符a为例,和数字三进行两次异或运算,可以看出最终得到的结果还是a。

由于是位运算,参与运算的参数必须要转化成二进制后才能参与运算。上面的算法public static String xor(String content, Integer key)中,首先要将content转化成一个字符数组,然后将数组的每一个字符,和整形的key做异或运算得到新的字符,最终,将新的字符数组转化成新的字符串。

为什么不能使用content字符串直接与key求异或运算?因为字符串不能直接与数字运算,但是字符可以与数字运算,所以字符串转换成字符数组。

下面介绍的加密解密方法的底层,使用的都是二进制,所以加密解密的参数最终都会转换成二进制字节数组的形式进行处理。

上面这种方法中,加密和解密使用的是相同的密钥key,我们通常将这种方式称为对称加密。如果加密和解密使用的是不同的秘钥,则称之为非对称加密。

三、对称加密

对于对称性加密,双方通讯之前,都要事先知道相同的密匙和算法,之后便是对数据进行加解密了。

这里介绍几种常见的对称加密算法:DES,AES。

3.1 DES

DES(Data Encryption Standard) 算法是美国政府机关为了保护信息处理中的计算机数据而使用的一种加密方式,是一种常规密码体制的密码算法,目前已广泛使用。该算法输入的是64比特的明文,在64比特密钥的控制下产生64比特的密文;反之输入64比特的密文,输出64比特的明文。64比特 的密钥中含有8个比特的奇偶校验位,所以实际有效密钥长度为56比特。使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行"异或"运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

下面是使用JDK进行加密的示例代码:

package com.wuxiaolong.EncrypteDecrypt;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.util.Base64;

/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-07-23
 */
public class DESUtil {/** * 偏移变量,固定占8位字节 */private final static String IV_PARAMETER = "12345678";/** * 加密算法 */private static final String ALGORITHM = "DES";/** * 加密/解密算法-工作模式-填充模式 */private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";/** * 默认编码 */private static final String CHARSET = "utf-8";/** * 秘钥 */private static final String KEY = "key12345678";public static void main(String[] args) {String content = "我爱你";String encptStr = encrypt(KEY,content);System.out.println(encptStr);String decptStr = decrypt(KEY,encptStr);System.out.println(decptStr);}/** * 生成key * * @param password * @return * @throws Exception */private static Key generateKey(String password) throws Exception {DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);return keyFactory.generateSecret(dks);}/** * DES加密字符串 * * @param password 加密密码,长度不能够小于8位 * @param data 待加密字符串 * @return 加密后内容 */public static String encrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);// 加密byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));// base64编码JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoderbyte[] encode = Base64.getEncoder().encode(bytes);return new String(encode);} catch (Exception e) {e.printStackTrace();return data;}}/** * DES解密字符串 * * @param password 解密密码,长度不能够小于8位 * @param data 待解密字符串 * @return 解密后内容 */public static String decrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);// base64解码byte[] decode = Base64.getDecoder().decode(data.getBytes(CHARSET));// 解密byte[] decrypt = cipher.doFinal(decode);return new String(decrypt, CHARSET);} catch (Exception e) {e.printStackTrace();return data;}}
} 

上面代码运行的结果:

Xii999DE7LPx5io0awfOFw==// 加密结果
我爱你 // 解密结果 

DES是一种分组数据加密技术(先将数据分成固定长度的小数据块,之后进行加密),速度较快,适用于大量数据加密,比如文件加密。文件加密的代码,可以关注我的公众号,输入关键字“java-summary”获取。

1997 年RSA数据安全公司发起了一项“DES 挑战赛”的活动,志愿者四次分别用四个月、41天、56个小时和22个小时破jie了其用56bit DES算法加密的密文。即DES加密算法在计算机速度提升后的今天被认为是不安全的。所以针对保密级别特别高的数据推荐使用非对称加密算法。

3.2 AES

AES (Advanced Encryption Standard),高级加密标准,是一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

DES使用56位密钥,比较容易被破jie,而AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据,相对来说安全很多。完善的加密算法在理论上是无法破jie的,除非使用穷尽法。使用穷尽法破jie密钥长度在128位以上的加密数据是不现实的,仅存在理论上的可能性。统计显示,即使使用目前世界上运算速度最快的计算机,穷尽128位密钥也要花上几十亿年的时间,更不用说去破jie采用256位密钥长度的AES算法了。

下面是AES的源码展示:

package com.wuxiaolong.EncrypteDecrypt;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-07-23
 */
public class AESUtil {/** * 加密算法 */private static final String ALGORITHM = "AES";/** * 秘钥长度 */private static final Integer KEY_LENGTH = 128;/** * 默认编码 */private static final String CHARSET = "utf-8";/** * 秘钥 */private static final String KEY = "key12345678";public static void main(String[] args) throws Exception {String content = "我爱你";String encrypt = encrypt(content, KEY);System.out.println(encrypt);String decrypt = decrypt(encrypt, KEY);System.out.println(decrypt);}/** * 生成key * * @param password * @return * @throws Exception */private static SecretKeySpec generateKey(String password) throws Exception {// 创建AES的Key生产者KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);// 利用用户密码作为随机数初始化出// SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行kgen.init(KEY_LENGTH, new SecureRandom(password.getBytes()));// 根据用户密码,生成一个密钥SecretKey secretKey = kgen.generateKey();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回byte[] enCodeFormat = secretKey.getEncoded();// 转换为AES专用密钥SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM);return key;}/** * AES加密字符串 * * @param content 需要被加密的字符串 * @param password 加密需要的密码 * @return 密文 */public static String encrypt(String content, String password) {try {SecretKeySpec key = generateKey(password);// 创建密码器Cipher cipher = Cipher.getInstance(ALGORITHM);byte[] byteContent = content.getBytes(CHARSET);// 初始化为加密模式的密码器cipher.init(Cipher.ENCRYPT_MODE, key);// 加密byte[] result = cipher.doFinal(byteContent);// 二进制转换成16进制字符串String hexStr = parseByte2HexStr(result);return hexStr;} catch (Exception e) {e.printStackTrace();}return null;}/** * 解密AES加密过的字符串 * * @param content AES加密过过的内容 * @param password 加密时的密码 * @return 明文 */public static String decrypt(String content, String password) {try {// 十六进制字符串转换成二进制字节数组byte[] byteArr = parseHexStr2Byte(content);SecretKeySpec key = generateKey(password);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key);// 解密byte[] result = cipher.doFinal(byteArr);return new String(result,CHARSET);} catch (Exception e) {e.printStackTrace();}return null;}/**将二进制转换成16进制 * @param buf * @return */public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/**将16进制转换为二进制 * @param hexStr * @return */public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length()/2];for (int i = 0;i< hexStr.length()/2; i++) {int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);result[i] = (byte) (high * 16 + low);}return result;}
} 

上面代码运行的结果:

765B2080D288F81355CB2A235AD7938C// 加密结果
我爱你 // 解密结果 

相较于DES而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高了,被称为下一代加密标准。目前世界上还有组织在研究如何攻破AES这堵坚厚的墙,但是因为破jie时间太长,AES得到保障,但是所用的时间不断缩小。随着计算机计算速度的增快,新算法的出现,AES遭到的攻击只会越来越猛烈,不会停止的。

AES现在广泛用于金融财务、在线交易、无线通信、数字存储等领域,经受了最严格的考验,但说不定哪天就会步DES的后尘。

3.3 对称加密的特点

优点:

  • 速度快。相对于非对称加密,对称加密的性能更好,加解密速度更快。

  • 安全。只能说相对还是安全的。

  • 紧凑。加密后内容的长度基本变化不大。

缺点:

  • 如果双方通讯时,通过明文传输共享密钥,容易出现中途劫持和窃听的问题。

  • 随着通讯的参与者数量的增加,密钥数量急剧膨胀((n×(n-1))/2)。

  • 因为密钥数量过多,对密钥的管理和存储是一个很大的问题(后面我会专门开一期说秘钥管理及系统设计)。

  • 不支持数字签名和不可否认性。

四、非对称加密

对于非对称算法,双方通讯之前,都需要事先生成一对密匙(公钥、私钥),然后双方交换公钥。通常非对称加密使用的就是RAS算法。

在使用非对称密钥技术之前,所有参与者,不管是用户还是路由器等网络设备,都需要预先使用非对称密钥算法(例如RSA)产生一对密钥,其中包括一个公钥和一个私钥。公钥可以放在一个服务器上共享给属于这个密钥系统的所有用户与设备,而私钥需要由持有者严格保护,确保只有持有者才能唯一拥有。

非对称加密有很多优点,安全、公钥可以网络传输等。但是加密速度很慢,不会用来加密上KB的数据。

关于RAS算法,可以说的内容太多太多,比如RSR的数学原理、公钥加密私钥解密、私钥签名公钥验签、公私钥生成、大文件如何加密、秘钥如何管理等问题。这些我都会在这个安全系列的其他文章中详细说明的。这一期以代码展示为主,就不过多在这里说了。

4.1 RSA

这里需要注意的是,加密使用的是对方的公钥,解密使用的是对应的私钥。

package com.wuxiaolong.EncrypteDecrypt;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-07-24
 */
public class RSAEncrypt {//用于封装随机产生的公钥与私钥private static Map<Integer, String> keyMap = new HashMap<Integer, String>();public static void main(String[] args) throws Exception {//生成公钥和私钥genKeyPair();//加密字符串String message = "我爱你";System.out.println("随机生成的公钥为:" + keyMap.get(0));System.out.println("随机生成的私钥为:" + keyMap.get(1));String messageEn = encrypt(message,keyMap.get(0));System.out.println(message + "\t加密后的字符串为:" + messageEn);String messageDe = decrypt(messageEn,keyMap.get(1));System.out.println("还原后的字符串为:" + messageDe);}/** * 随机生成密钥对 * @throws Exception */public static void genKeyPair() throws Exception {// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器,密钥大小为keyPairGen.initialize(2048,new SecureRandom());// 生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私钥、公钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 得到私钥字符串String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));// 将公钥和私钥保存到Map0表示公钥1表示私钥keyMap.put(0,publicKeyString);keyMap.put(1,privateKeyString);}/** * RSA公钥加密 * @param str 加密字符串 * @param publicKey 公钥 * @return 密文 * @throws Exception 加密过程中的异常信息 */public static String encrypt( String str, String publicKey ) throws Exception{//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);String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/** * RSA私钥解密 * @param str 加密字符串 * @param privateKey 私钥 * @return 明文 * @throws Exception 解密过程中的异常信息 */public static String decrypt(String str, String privateKey) throws Exception{//64位解码加密后的字符串byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));//base64编码的私钥byte[] decoded = Base64.decodeBase64(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}

} 

代码运行的结果:

随机生成的公钥为:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgJW1vVhZWd8NDiTIrAJK5N4EipP5jWw8WIsWiX3SzZGpzRuz5duRjhubxS2kOoGP6GnOI8KMAHwcFCjtgQNLfvoufHG9OiRaKQEkPhypF1vsuEC0rzeOcWbzIAsWk7B6wboGd6Or4L2MAHsIrluISgICq6BU1cVb/XSPX9tbIOfrjRNsbX5DnNd39XZ4yUlqIDocCQtV3rmQlG4e4nlsJTw073/7/eNCkp7FMJVTch+rQspUPlks9V1ic9TmBhW7dszAGWz4BmIe1elar5bapivBtnVpRX+yEGZSQWkchTqSQTOeYfuh3GFDAYoWlGEx+OeUX8SsRK1V3zeiwv6lpQIDAQAB
随机生成的私钥为:
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCAlbW9WFlZ3w0OJMisAkrk3gSKk/mNbDxYixaJfdLNkanNG7Pl25GOG5vFLaQ6gY/oac4jwowAfBwUKO2BA0t++i58cb06JFopASQ+HKkXW+y4QLSvN45xZvMgCxaTsHrBugZ3o6vgvYwAewiuW4hKAgKroFTVxVv9dI9f21sg5+uNE2xtfkOc13f1dnjJSWogOhwJC1XeuZCUbh7ieWwlPDTvf/v940KSnsUwlVNyH6tCylQ+WSz1XWJz1OYGFbt2zMAZbPgGYh7V6VqvltqmK8G2dWlFf7IQZlJBaRyFOpJBM55h+6HcYUMBihaUYTH455RfxKxErVXfN6LC/qWlAgMBAAECggEAe+FAFWpfsuDcsAqqNmWDCBoJoATOAP0M6nUdwlqxVBGI2K1e1Q2Dnrhki0Pcm+0k2tHMotEUlob7ekSwBIJLIssfLA9cMf7Byg1qgFiWY4XRevYD3WcV2ZVImE92cdUtfySchHjv53ZVwkTGaUyP8lUbg4PVF5qrdHTuiHhJxFmqLwB6DC7HM9X2jleYJaNSZ2UwiloqkHAMDhqAu9212qZ4ISjbOg/iHDeTRKG3wIX989rsxAVSsruQm3DMZ/jeXzx8MpNjiLaT448dDSOhjhb1tOycMI7CWhYsuT7fOSFmtCtb9E3L8AVarKD2eiOqMaXj28wiuoST7lxa26hHoQKBgQDSmLPYHLXgOfJPIjuYv3IrBv9wr6H9N5FnSKYfISo8gQZJj4YWVFsc9/9vQyOOk0VvtSd28z0dixo1P4axEFe84vwVUsbgo7797nFLZWFm6tZZLgDiSgcxLhz9/5cjnY7irZMdPqKWQKkcFMm4Km8JX8BipwKVwuDiZ74enE1viQKBgQCcTpi0IxOaQQXWaDjG50MBBUIU0F1vM69apsJKeIY8XgE9Vsz/4yqwW7enIZHY15yx4btmZ/1ieOTqRI3x6SwFcgRZQD8OiKf/6WpHp7hXmTE34QJd9CPq+c8MgImd9BAX4rsdKp9pOGsTjFcAvLkU1crk/JQdht+p6VErJUwCPQKBgHLcFjqobgn9kMrYQOjugbY1+tva7t7Mj+FlHjWcQQz+0g8M2HUVTRxfplForNv2NsjWZM/bmlmipIimPTAVWcULh7GZlB6xMFoO0nvsr1MSghXhoVnKRmHsZKOj4yrppCS9xp8MqmCIo7NNIzfu7OCP+L3VmPNVdpIFQwwu840BAoGAUJx8RpK8flZAc3YmqfYE6VbT4LYhKcOHEQJlu1BzMljs3LySVvnKP0/d5FT8yc9Q4bBgHI1O8WUV8ffPGM6/REOsGHd4zb8OnX28sR2/hXXdG0txFBFgIMQa0wDLeGmxjxAAnicoNXTCTD+Zcyjhbuxfij71CFFRsmhA0zaV/6UCgYEAua9INHaJQ5VIFEyAWMHhfwQOU00BynQP0MugNwPypH9qejEzzBJ2fq8j69fxfeG2EENIiDymZMPwHybpYcipKT1aksCPu95HF1+yR6lNrSFDzn/kQu06bgB3V61wsgsKeDuDh++z381m1BONfK3MS1+BlxR/pJ59ikBLyB15tiQ=
我爱你	加密后的字符串为:
Qo2qkCPF27rfbfAV8k3uLH4ogVA8BlnhtKEvL77KH6wZQKmzrq3z794TuWU9PbJpkYLD2tALt6t0y+Rr9rpPHCqtAGXkzDddu7get/8eNs4N3i8yoOYW2ui7yny7v5cVd8ZsxSHcszmaSV+wb+5AJcMzQhOvWaRwx1WVEOkDp/qBENGFdfPJ8gecbL7YgnqzUtccaJQomQWIlXk88mAU8nAALHO/goEI2CK1HRtb+9qyQgjHU1zFhBsli5yA8NDcqiczFb/nV90yKLMhn5DpIm3gU/qquQltfnkflSk+KXe5BFThIVxcu2FBIovOaX+s82L4DJXtRZS+aCSrHOPfSg==
还原后的字符串为:我爱你 

加密解密使用的秘钥和签名验签的秘钥使用不一样,参考这个系列的其他文章。

4.2 非对称加密的特点

工作特点:

  • 用一个密钥(公钥)加密的数据,只能用另一个密钥(私钥)来解密。

  • 一个密钥(私钥)用来签名,一个密钥(公钥)用来验签。

优点:

  • 由于不必担心交换的公钥被劫持,所以非对称密钥的分发更安全。

  • 密钥数目和参与者数目相同。

  • 在交换公钥之前,不需要预先建立某种信任关系。

  • 支持数字签名和不可否认性。

缺点:

  • 加密速度很慢。要不用来加密上KB的数据,可以用来加密key,key的数据量较小。

  • 加密后,密文会变长。

关注公众号,输入“java-summary”即可获得源码。

完成,收工!

【传播知识,共享价值】,感谢小伙伴们的关注和支持,我是【诸葛小猿】,一个彷徨中奋斗的互联网民工!!!

Java中的AES加密和解密(CBC模式) 通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法。在本文中,我们将讨论Java中具有CBC模式的AES(高级加密标准)对称加密算法,比3DES更快,更安全。 加密方式 众所周知,加密有2种基本类型-非对称和对称加密。 非对称加密使用两个不同的密钥作为公共密钥和私有密钥,您可以在此处... 阅读详情

相关推荐

java加密解密应用——DES算法

应用领域:IC卡,POS机,ATM机,加油站,高速公路收费站。应用场景:信用卡持卡人的PIN的加密传输,IC卡与 POS机之间的双向认证。算法入口参数:KEY,Data,Modekey:DES算法的工作密钥Mode:DES算法的工作模式(加密|解密)Data:需要加密或解密的数据工作方式:如果Mode为加密模式,则用key对数据data进行加密处理,生成data的密码模式如果Mode为解密模式,则用key对数据data进行解密处理,还原data的明码模式这样,在通信网络的两端,双方约定好一致的key,源端用

JavaMan_chen的专栏 6026

java-通过异或(xor)实现快速加解密的方法

运算规则如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。更容易记忆的规则(半加运算)异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。所以异或常被认作不进位加法。异或不常用,几天不不碎碎念几遍规则,有个2周就把它忘干净了!!!。首先说RandomAccessFile是个很强大的类,读写文件不丢内容。

草青工作室 的专栏 1805

Java中AES加密和解密的方法分享

/返回基本编码格式的密钥,如果此密钥不支持编码,则返回。kgen.init(128,newSecureRandom(password.getBytes()));System.out.println("解密后的内容"+newString(decrypt,"utf-8"));System.out.println("加密后的2进制密文"+newString(encrypt));System.out.println("加密后的2进制密文"+newString(byte2));...

Moonxiyue的博客 3334

【Java】Java实现简单异或加密

异或加密如果同时知道原文和密文,则对比原文和密文可以推算出密钥,因此异或加密安全性较低,一般只用于简单的加密。

有知识,世界会更大 1169

Unity3D用c#脚本调用前端javascript函数:H5获取unity - webgl 加载并初始化完成的消息

unity3d发布的Webgl 可以作为静态文件加载到H5页面中,并通过javascript 调用unity内置的C#脚本函数,详见Webgl调用unity api。而往往我们需要知道Webgl ready的消息,本文将给出unity 内部调用javascript函数的方案加以解决。

Bravo 2476

Ventoy引导自定义菜单配置详解:手把手教你用ventoy_grub.cfg启动硬盘里的Manjaro

本文详细解析了Ventoy引导自定义菜单配置方法,重点介绍如何通过ventoy_grub.cfg文件启动硬盘中的Manjaro系统。从Ventoy与GRUB2的协作原理到具体配置步骤,包括分区布局设计、关键参数解析及常见问题解决方案,帮助用户实现多系统引导的灵活管理。

weixin_28738165的博客 299

JAVA文件内容加密(异或^方式)

【代码】JAVA文件内容加密(异或^方式)

piaoyunlive的博客 1356

开关电源EMC整改实录:用WSX系列共模电感搞定30MHz辐射超标

本文详细介绍了开关电源EMC整改实战,通过WSX系列共模电感成功解决30MHz频段辐射超标问题。文章分析了共模干扰的产生机制,对比了不同磁芯材料的性能差异,并提供了电路布局优化与安装技巧,最终通过实测数据验证了整改方案的有效性。

weixin_29305313的博客 414

Java 实现异或(xor)算法的加密和解密

异或(xor)加密原理 一个整数 a 和任意一个整数 b 异或两次,得到的结果是整数 a 本身,即: a == a ^ b ^ b。这里的 a 就是需要加密的原数据,b 则是密钥。a ^ b 就是加密过程,异或的结果就是加密后的密文;密文 (a ^ b) 再与密钥 b 异或,就是解密过程,得到的结果就是原数据 a 本身。

谢TS的博客 1万+

LobeHub开源AI应用平台:从部署到定制的全栈实践指南

在现代AI应用开发领域,大语言模型(LLM)的集成与部署是核心技术挑战之一。其原理在于通过API或本地化部署,将预训练模型的强大能力封装为可调用的服务。这项技术的核心价值在于极大地降低了AI应用的开发门槛,使开发者能够快速构建智能对话、内容生成等场景的应用。随着模型即服务(MaaS)模式的普及,一个关键痛点是如何高效地管理多模型、设计友好的用户界面并实现功能扩展。这正是开源项目LobeHub所聚焦的领域,它通过提供可插拔的架构和配置驱动的低代码理念,解决了AI能力落地的“最后一公里”问题。本文将结合Dock

weixin_27210125的博客 752

4万字一文带你看懂车载摄像头技术、市场、发展前景

1、小孔成像 在战国初期,我国学者墨子(公元前468年-公元前376年)和弟子们完成了世界上第一个小孔成像的实验,并记录在《墨经》中:“景到,在午有端,与景长。说在端。”“景。光之人,煦若射,下者之人也高;高者之人也下。足蔽下光,故成景于上;首蔽上光,故成景于下。在远近有端,与于光,故景库内也。” 此文解释了小孔成倒像的原因,指出了光沿直线传播的性质。这是对光直线传播的第一次科学解释。 而西方世界直到公元前350年,古希腊学者亚里士多德提出光学法则,西方人从此了解小孔成像的光学原理。

m0_58838529的博客 1495

JAVA各种加密与解密方式

信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。//信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。/*** @param input 明文* @param algorithm 算法 MD5 | sha-1 SHA-256 |* @return 密文 Base64 & Hex*///0xff是16进制数,这个刚好8位都是1的二进制数,而且转成int类型的时候,高位会补0//只取得低八位。

【有梦想的菜】的博客 1万+

WPF实战案例 | C# WPF实现大学选课系统

WPF实战案例_C# WPF实现大学选课系统, C# WPF实现大学选课系统,大作业,毕业设计,该系统实现多身份登录、修改密码、课程的管理,个人信息的管理等功能。这个源码让你快速搭建自己的应用程序,注释完整,代码规范,各种风格都有,代码上手简单,代码独立,可以直接用程序打开,运行使用。也可直接点击EXE运行程序。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 4624

Java 实现 AES 对称加密算法的加密和解密

AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,加密和解密使用相同的密钥。Java 代码实现 AES 加密/解密 一般步骤:先根据原始的密码(字节数组/字符串)生成 AES密钥对象;再使用 AES密钥对象 加密/解密 数据。为了方便直接使用,将 AES 加密/解密相关方法封装成工具类,并且支持对文件的 AES 加密/解密。

谢TS的博客 3万+

SQL中的时间计算:员工每日工作时长

摘要:本文介绍了一个使用SQL查询计算员工每日工作时长的实用方法。通过分析包含员工打卡记录的数据库表,利用CTE(公共表表达式)将日期分组,计算最早和最晚打卡时间差,最终以"小时:分钟"格式输出工作时长。该方法适用于每日两次打卡的场景,并提示了处理漏打卡等特殊情况时的注意事项,为企业考勤管理提供了有效的数据支持方案。(148字)

m0_74337424的博客 412

小目标检测难题终结:YOLOv11 + 注意力机制,精度直接拉满

如果你在实操中遇到精度提升不明显或速度下降过多的问题,不妨尝试调整注意力模块的类型(如替换为CA)或插入层级,或针对性优化小目标的数据集增强策略。记住,小目标检测的核心是“特征强化与空间定位”,只要结合业务场景灵活调整注意力模块的组合,你也能让YOLOv11在小目标识别任务中脱颖而出。接下来,我们从模块选型到代码落地,一步步带你打造“小目标检测专精版”YOLOv11,真正帮你解决工业场景中(如安防、质检)的小目标识别痛点。在城市安防场景中,改进后的YOLOv11对远处行人、车辆(小目标)的识别准确率提升。

m0_64661770的博客 199

Java 实现 AES 加密和解密完整示例

AES,全称为 Advanced Encryption Standard,是一种分组密码算法,用于保护敏感数据的传输和存储。AES 分为 128 位和 256 位两种密钥长度,可以对数据进行加密和解密,保证数据的安全性和完整性。AES 主要应用于电子商务、移动支付、网络安全等领域,被广泛运用于现代社会的各个方面。AES 算法被设计为高度安全,可以在理论上保证其分组密码的安全性。然而,由于其复杂性和密钥长度,AES 算法的实现和应用也具有一定的技术难度。

蜗牛的博客 3万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

JAVA实现AES加密、解密

什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。 那么为什么原来的DES会被取代呢,,原因就在于其使用56位密钥,比较容易被破解。而AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据,相对来说安全很多。完善的加密算法在理论...

DamonREN的博客 3万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java RSA加密/解密(附带源码)

java RSA加密/解密(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 2668

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Q安全机制(加密、解密等).java

本文全面介绍了Java中的加密解密技术,包括对称加密(AES)、非对称加密(RSA)和哈希算法(SHA系列)三大类。对称加密使用相同密钥进行加解密,速度快但密钥分发困难;非对称加密采用公钥/私钥机制,解决了密钥分发问题但速度较慢;哈希算法用于数据完整性验证,生成不可逆的"数字指纹"。文章通过代码示例展示了各类算法的Java实现,并建议在实际应用中综合使用这些技术,如用AES加密数据、RSA加密密钥、SHA校验完整性。最后强调密钥管理的重要性,提出使用强密钥、定期

m0_66709139的博客 850

Java字符串的加密解密

为了保证程序的安全,经常采用数据加密的方法。Java 中提供了专门用于加密运算的类和接口。 除了使用加密类和接口外,还可以通过多种方式实现字符串的加密。其中常用的就是获取字符串的字节数组,之后对字节数组中的每个字节都进行运算,得到新的内容,这时所获得的字符串与原字符串将不相同,以此达到加密的效果;解密时再将加密字符串进行相反的运算,这样即可得到原字符串。 本实例简单介绍如何通过数据运算实现字符串的...

jijiangpeng的博客 1万+

【数据安全】Java AES加密和解密

对称密钥分组密码在数据加密中起着重要作用。这意味着加密和解密都使用相同的密钥。高级加密标准(AES)是一种广泛使用的对称密钥加密算法。在本教程中,我们将学习如何在JDK中使用Java Cryptography Architecture(JCA)实现AES加密和解密。

全网:架构师研究会 1615

java加密解密工具类(EncryptUtils)

是一个自定义的 Java 工具类,用于封装常见的加密和解密算法,如 MD5、SHA-1、SHA-256、AES、DES 等。这个工具类提供了简单易用的接口,使开发者能够方便地进行数据的加密、解密、签名和验证操作。旨在简化加密解密的过程,减少错误的发生,并提高代码的可读性和维护性。EncryptUtils是一个Java加密解密工具类,它提供了一些常用的加密解密算法,可以用于保护敏感数据的安全性。

Flying_Fish_roe的博客 5099
上一篇: 安全团队干饭吃,DoS攻击竟让美国金融巨头崩溃
下一篇: 安卓 https 证书校验和绕过
gool奇米
博客等级 码龄4年 16粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值