【Java技术专题】「入门到精通系列」深入探索Java技术中常用到的六种加密技术和代码

news2024/11/27 15:34:58

深入探索Java技术中常用到的六种加密技术和实现

  • 背景介绍
    • 柯克霍夫原则
    • 加密机制
      • 加密类型
      • 密码学原则
  • 加密常用代表组件
  • 加密算法介绍
    • Base64算法
    • 消息摘要算法(Message Digest)
      • 数据指纹
      • MD5
        • MD5算法的工作原理
      • SHA
        • SHA工作原理
    • 对称加密
      • DES
        • DES的原理分析
      • 3DES3DES
      • AES
        • AES加密算法
      • PBE
    • 非对称加密
      • RSA
      • DH算法

背景介绍

重点记住现代密码学的柯克霍夫原则:数据安全取决于密钥而不是算法的保密。即使密码系统的细节已经公开,只要密钥保密,系统依然可以保持安全。本文介绍了6种常用的加密技术和相应的代码实现。

柯克霍夫原则

柯克霍夫原则(Kerckhoffs’s principle)是密码学中的一个重要原则,提出者为荷兰的密码学家Auguste Kerckhoffs。该原则指出,一个密码系统的安全性不应依赖于保密算法,而应仅仅依赖于秘密密钥的保密。换言之,即使密码系统的算法细节被公开,只要密钥保持保密,该系统仍然应该是安全的。

加密机制

加密是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些资料将加密直接分为对称加密和非对称加密)。

加密类型

  • 双向加密是指对明文进行加密后生成密文,可以使用相应的算法解密还原成明文。
  • 单向加密只是对信息进行摘要计算,无法通过算法反向生成明文。

严格来说,单向加密不能被视为加密的一种形式,而更应该被称为摘要算法。

密码学原则

  • 系统必须是可用的,但不一定需要是数学上无法解码的。可用性指的是系统在需要时能够正常工作,而无法解码表示系统的安全性不应依赖于数学算法的保密性。
  • 系统不必保密,即使落入敌手手中也不会泄露关键信息。这强调了即使系统被敌人获得,其安全性也不应受到过多威胁。
  • 密钥必须可以在不经书写的情况下进行资料交换和记忆,并且双方能够更改密钥。这意味着密钥管理应该方便,而且能够在通信双方之间轻松地进行。
  • 系统可用于电讯,表示该系统适用于电信领域,可以在通信过程中使用。
  • 系统可以转移位置,其功能不受几个人之间传递的影响。这说明系统设计要能够在位置转移时保持功能完整性。
  • 系统易于使用,不要求用户过多思考或遵循复杂的规则。这表明系统设计应考虑到用户友好性,不过分要求用户的脑力劳动。

加密常用代表组件

主要的加密方式代码提供方主要有以下几个:

  1. JDK:Java Development Kit(JDK)提供了一套完整的加密API,相关的代码位于Java安装目录下的jre\lib\jce.jar包中。
  2. Apache Commons Codec:Apache公司提供了一个名为Commons Codec的开源项目,其中包含了常用的编码和加密方式的实现,可以在其官方网站(http://commons.apache.org/proper/commons-codec/)获取相关代码和文档。
  3. Bouncy Castle(BC):Bouncy Castle是一个加密算法提供方,提供了丰富的密码学功能和算法实现,可以在其官方网站(http://www.bouncycastle.org/java.html)获取相关代码和文档。

对于基本常用的加密需求,使用JDK提供的加密API已经足够。如果需要更多功能或特殊算法的支持,可以考虑使用Apache Commons Codec或Bouncy Castle。

加密算法介绍

Base64算法

从现代加密算法的复杂性来看,Base64等编码方式并不足以被称为真正的加密算法,然而对于那些不太熟悉计算机的人来说,Base64已经足够满足一般需求。

  • 加密本质Base64算法基于64个基本字符,加密后的string中只包含这64个字符
  • 使用场景:Base64编码常用于处理URL或任何你不希望普通人直接理解的数据。通过对数据进行Base64编码处理,可以在网络上发布编码后的数据,避免普通人一眼就知道其内容

采用Base64编码可以使数据具有一定的不可读性,即所编码的数据无法直接被肉眼读取,下面便是Base64的加密算法的代码案例:~

import java.util.Base64;
public class Base64Utils {
 public String encode(String src) {
    byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes());
     return new String(encodeBytes);
 }
 public String decode(String src) {
    byte[] decodeBytes = Base64.getDecoder().decode(src.getBytes());
   return new String(decodeBytes);
  }
}

消息摘要算法(Message Digest)

消息摘要(Message Digest),也被称为数字摘要(Digital Digest),是一种通过单向哈希加密函数对消息或文本进行作用而生成的固定长度值。该值是消息的独特表示,且无法从摘要逆向推导出原始消息。

  • 加密本质:消息摘要通过单向哈希加密函数将消息转换为固定长度的值,并具备以下特点:唯一性、不可逆性以及对数据的微小修改具有较大的影响
  • 使用场景:哈希函数的抗冲突性使得即使原始消息稍有变化,就算只改变了一段文字的一个字母,通过哈希算法生成的摘要值也会完全不同。这样,即使有微小的改动,哈希值也会发生显著的变化,提供了对数据完整性和一致性的可靠检验

哈希算法的单向性使得查找两个不同输入消息具有相同哈希值几乎不可能的

数据指纹

每段数据都应该是独一无二的,与人类一样,人类可以通过指纹和DNA来作为唯一标识。而数据的唯一标识是什么呢?

数据的指纹可以通过消息摘要算法生成的字符串来表示。例如,在注册网站时,客户端向服务器传输的应该是经过密码进行消息摘要处理后的内容。这样,即使服务器被攻破,黑客也无法得知用户的真实密码。然而,现在有报道称MD5和SHA等算法已被攻破。因此,我们需要进行多次迭代加密,以增强安全性。至少加密2次以上,以防止别人轻易破解。

MD5

MD5(Message Digest Algorithm 5,消息摘要算法 5)是一种常用的哈希函数,它将任意长度的消息作为输入,并输出一个固定长度(通常为128位)的哈希值。MD5算法使用非线性和循环的方式对输入数据进行压缩,并生成唯一的摘要值。

MD5算法的工作原理

  • 初始化:MD5算法会初始化一个128位的缓冲区,并设置一些预定义的常量。
  • 对其填充:如果输入消息的字节长度不是64的倍数,MD5算法会将其填充到能够被64整除的字节数,填充规则为在消息末尾添加一个1,然后填充0直到长度满足要求。
  • 拆分处理:MD5算法将填充后的消息拆分成512位(64字节)的块,然后对每个块进行处理。
  • 压缩函数:MD5算法通过执行一系列的位操作和非线性函数来处理每个块,并更新缓冲区的状态。
  • 输出:经过处理后,MD5算法会将最终的缓冲区状态作为最终的摘要值输出。

注意,由于MD5算法已被发现存在碰撞漏洞(即两个不同的输入可能会生成相同的摘要值),因此在一些安全性要求较高的场景中,建议使用更安全的哈希算法,如SHA-256等。

以下是MD5加密算法的代码示例(Java语言):

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
 * 消息摘要算法
 */
public class MD5Strategy implements IStrategy{
 public String encode(String src) {
	 try {
	  MessageDigest md = MessageDigest.getInstance("MD5");
	  byte[] encodeBytes = md.digest(src.getBytes());
		  return Hex.encodeHexString(encodeBytes);
	 }catch (NoSuchAlgorithmException e) {
		  e.printStackTrace();
	 }
 	 return null;
 }
 public String decode(String src) {
	 throw new RuntimeException("MD5 no decode");
 }

SHA

SHA算法具有较高的安全性和抗碰撞性,能够生成唯一的哈希值。然而,由于计算速度较慢,现在一些安全性要求较高的领域可能更倾向于使用SHA-3系列算法,如SHA-256、SHA-512等。

SHA工作原理

  • 初始化:SHA算法会初始化一个哈希值缓冲区,并设置一些预定义的常量作为初始值。
  • 对齐填充:如果输入消息的字节长度不满足特定要求(例如512位对于SHA-256),SHA算法会进行填充操作以保持长度一致。
  • 拆分处理:SHA算法将填充后的消息分成固定大小的块(通常为512位),对每个块进行处理。
  • 压缩函数:SHA算法通过执行一系列位操作和非线性函数来处理每个块,并根据当前块和上一个块的状态更新哈希缓冲区。
  • 输出:经过处理后,SHA算法会将最终的哈希值从哈希缓冲区中输出。

以下是SHA加密算法的代码示例(Java语言):

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
public class SHAStrategy {
    public String encode(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(src.getBytes());
            return Hex.encodeHexString(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    public String decode(String src) {
        throw new RuntimeException("SHA no decode");
    }

注意,代码中使用了Apache Commons Codec库中的Hex类来将字节数组转换为十六进制字符串。如果要运行此代码,需要确保已导入该库。

对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。而因为加密和解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。当然,安全性较低带来的优点就是优计算量小、加密速度快、加密效率高。

DES

DES(Data Encryption Standard),中文名为“数据加密标准”,是一种使用密钥进行加密的块密码算法。DES算法是密码体制中的对称密码体制,也被称为美国数据加密标准。它是在1972年由美国IBM公司研制的对称密码体制加密算法。

DES的原理分析

DES算法将明文按照64位进行分组,密钥长度为64位,但实际参与DES运算的是56位的密钥(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)。通过按位替代或交换的方式,将分组后的明文和56位的密钥进行加密,生成密文组。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Hex;
public class DESStrategy implements {
    private Cipher cipher;
    private SecretKey generateKey;

    public String encode(String src) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
            keyGenerator.init(56); // size
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();
            DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
            generateKey = secretKeyFactory.generateSecret(desKeySpec);
            cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, generateKey);
            byte[] resultBytes = cipher.doFinal(src.getBytes());
            return Hex.encodeHexString(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String decode(String src) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, generateKey);
            byte[] result = Hex.decodeHex(src.toCharArray());
            return new String(cipher.doFinal(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

注意,由于DES算法的密钥长度较短(56位),已经不再足够安全,容易受到暴力破解等攻击。因此,在实际使用中,DES算法已经逐渐被更安全的加密算法如AES(Advanced Encryption Standard)所取代。

3DES3DES

3DES3DES,也就是“Triple DES”,中文名“三重数据加密算法”,它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密钥长度变得容易被暴力破解;

3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import org.apache.commons.codec.binary.Hex;

public class _3DESStrategy  {
    private Cipher cipher;
    private SecretKey generateKey;
    public String encode(String src) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
            keyGenerator.init(168); // size
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();
            DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
            generateKey = secretKeyFactory.generateSecret(desKeySpec);
            cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, generateKey);
            byte[] resultBytes = cipher.doFinal(src.getBytes());
            return Hex.encodeHexString(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String decode(String src) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, generateKey);
            byte[] result = Hex.decodeHex(src.toCharArray());
            return new String(cipher.doFinal(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

AES

AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准”,在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。

AES加密算法

AES 加密算法作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES 设计有三个密钥长度:128,192,256 位。相对而言,AES 的 128 密钥比 DES 的 56 密钥强了 1021 倍。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class AESStrategy{
    private Cipher cipher;
    private SecretKey generateKey;
    public String encode(String src) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128); // size
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();
            generateKey = new SecretKeySpec(keyBytes, "AES");
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, generateKey);
            byte[] resultBytes = cipher.doFinal(src.getBytes());
            return Hex.encodeHexString(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public String decode(String src) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, generateKey);
            byte[] result = Hex.decodeHex(src.toCharArray());
            return new String(cipher.doFinal(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

PBE

PBE,全称为“Password Base Encryption”,中文名“基于口令加密”,是一种基于密码的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。

PBE算法没有密钥的概念,把口令当做密钥了。因为密钥长短影响算法安全性,还不方便记忆,这里我们直接换成我们自己常用的口令就大大不同了,便于我们的记忆。

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.apache.commons.codec.binary.Hex;
/**
 * 基于口令的加密(password),对称 + 消息摘要
 */
public class PBEStrategy  {
    private Cipher cipher;
    private SecretKey generateKey;
    private PBEParameterSpec pbeParameterSpec;

    public String encode(String src) {
        try {
            SecureRandom secureRandom = new SecureRandom();
            byte[] salt = secureRandom.generateSeed(8);
            String password = "amuro";
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
            generateKey = secretKeyFactory.generateSecret(pbeKeySpec);
            pbeParameterSpec = new PBEParameterSpec(salt, 100);
            cipher = Cipher.getInstance("PBEWITHMD5andDES");
            cipher.init(Cipher.ENCRYPT_MODE, generateKey, pbeParameterSpec);
            byte[] resultBytes = cipher.doFinal(src.getBytes());
            return Hex.encodeHexString(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public String decode(String src) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, generateKey, pbeParameterSpec);
            byte[] result = Hex.decodeHex(src.toCharArray());
            return new String(cipher.doFinal(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

但是单纯的口令很容易被字典法给穷举出来,所以我们这里给口令加了点“盐”,这个盐和口令组合,想破解就难了。同时我们将盐和口令合并后用消息摘要算法进行迭代很多次来构建密钥初始化向量的基本材料,使破译更加难了。

非对称加密

非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥。需要注意的一点,这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,反之亦然。由于加密和解密使用的是两个不同的密钥,因此,这种算法叫做非对称加密算法。

RSA

其实,在早在 1978 年的时候,RSA就已经出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。其原理就如上面的工作过程所述。RSA 算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Hex;
public class RSAStrategy {
    private RSAPublicKey rsaPublicKey;
    private RSAPrivateKey rsaPrivateKey;

    public String encode(String src) {
        try {
            // 初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 私钥加密 公钥解密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] resultBytes = cipher.doFinal(src.getBytes());
           return Hex.encodeHexString(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String decode(String src) {
        try {
            // 私钥加密 公钥解密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));
            return new String(resultBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

DH算法

DH,全称为“Diffie-Hellman”,他是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议。由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成“一致”的、可以共享的密钥。也就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import org.apache.commons.codec.binary.Hex;
public class DHStrategy  {
    private Cipher cipher;
    private SecretKey receiverSecretKey;
    public String encode(String src) {
        try {
            // 初始化发送方密钥
            KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            senderKeyPairGenerator.initialize(512);
            KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair();
            PrivateKey senderPrivateKey = senderkeyPair.getPrivate();
            byte[] senderPublicKeyBytes = senderkeyPair.getPublic().getEncoded(); // 发送方的公钥

            // 初始化接收方密钥,用发送方的公钥
            KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyBytes);
            PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
            DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams();
            KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            receiverKeyPairGenerator.initialize(dhParameterSpec);
            KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
            PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
            byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic().getEncoded();
            KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
            receiverKeyAgreement.init(receiverPrivateKey);
            receiverKeyAgreement.doPhase(receiverPublicKey, true);
            receiverSecretKey = receiverKeyAgreement.generateSecret("DES");
            // 发送方拿到接收方的public key就可以做加密了
            KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
            x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyBytes);
            PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);
            KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
            senderKeyAgreement.init(senderPrivateKey);
            senderKeyAgreement.doPhase(senderPublicKey, true);
            SecretKey senderSecretKey = senderKeyAgreement.generateSecret("DES");
            if (Objects.equals(receiverSecretKey, senderSecretKey)) {
                cipher = Cipher.getInstance("DES");
                cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
                byte[] result = cipher.doFinal(src.getBytes());
                return Hex.encodeHexString(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public String decode(String src) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
            byte[] result = Hex.decodeHex(src.toCharArray());
            return new String(cipher.doFinal(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!

注意,DH算法是一种密钥协商算法,用于双方在不安全的通信信道上协商出一个共享密钥。在DH算法中,发送方和接收方通过交换各自的公钥来生成共享密钥。为了保证安全性,需要确保生成的共享密钥一致。在实际应用中,DH算法通常用于密钥协商,生成的共享密钥可以作为对称加密算法的密钥来进行加密和解密操作。

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

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

相关文章

性能优化(CPU优化技术)-ARM Neon详细介绍

本文主要介绍ARM Neon技术,包括SIMD技术、SIMT、ARM Neon的指令、寄存器、意图为读者提供对ARM Neon的一个整体理解。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC&#xff09…

VMware虚拟机和Centos7镜像安装

文章目录 安装VMware虚拟机1、下载2、激活 安装Centos7镜像启动虚拟机 安装VMware虚拟机 1、下载 建议还是安装16版本 VMware16下载 https://www.123pan.com/s/HQeA-aX1Sh VMware15 链接:https://pan.baidu.com/s/11UD1hb6IydbxNNPxmh-MqA?pwd0630 提取码&am…

2022年全国职业院校技能大赛(高职组)“云计算”赛项赛卷①第一场次:私有云

2022年全国职业院校技能大赛(高职组) “云计算”赛项赛卷1 第一场次:私有云(30分) 目录 2022年全国职业院校技能大赛(高职组) “云计算”赛项赛卷1 第一场次:私有云&#xff0…

DDC和PLC的区别

前言 PLC与DDC控制器的比较,一直以来在相关领域内受到广泛关注。每个人站在不同的角度分析,都会有不同的结论,我们今天聊聊这个话题。 基本定义和功能 可编程控制器PLC与直接数字控制器DDC,两者都由CPU模块、I/O模块、显示模块…

张量操作与线性回归

一、张量的操作:拼接、切分、索引和变换 (1)张量拼接与切分 1.1 torch.cat() 功能:将张量按维度dim进行拼接 • tensors: 张量序列 • dim : 要拼接的维度 torch.cat(tensors, dim0, outNone)函数用于沿着指定维度dim将多个张量…

CGAL的AABB tree

1、介绍 AABB树组件提供了一种静态数据结构和算法,用于对有限的三维几何对象集进行高效的交集和距离查询。可以查询数据结构中存储的几何对象集,以进行交集检测、交集计算和距离计算。 交集查询可以是任何类型的,只要在traits类中实现了相应的…

2024.1.1 hive_sql 题目练习,开窗,行列转换

重点知识: 在使用group by时,select之后的字段要么包含在聚合函数里,要么在group by 之后 进行行转列,行转列的核心就是使用concat_ws函数拼接(分隔符,内容), -- 以及collect_list函数进行收集,list不去重, set去重无序 列转行,核心就是使用炸裂函数把东…

DSL查询语法和RestClient查询文档

目录 DSL查询语法 DLS Query的分类 DSL Query基本语法 全文检索查询 精准查询 地理查询 复合查询 Function Score Query 复合查询 Boolean Query 搜索结果处理 排序 分页 分页 深度分页问题 深度分也解决方案 高亮 RestClient查询文档 快速入门 全文检索查…

将学习自动化测试时的医药管理信息系统项目用idea运行

将学习自动化测试时的医药管理信息系统项目用idea运行 背景 学习自动化测试的时候老师的运行方式是把医药管理信息系统项目打包成war包后再放到tomcat的webapp中去运行,于是我想着用idea运行会方便点,现在记录下步骤方便以后查找最开始没有查阅资料&am…

【心得】PHP反序列化高级利用(phar|session)个人笔记

目录 ①phar反序列化 ②session反序列化 ①phar反序列化 phar 认为是java的jar包 calc.exe phar能干什么 多个php合并为独立压缩包,不解压就能执行里面的php文件,支持web服务器和命令行 phar协议 phar://xxx.phar $phar->setmetadata($h); m…

LanceDB:在对抗数据复杂性战役中,您可信赖的坐骑

LanceDB 建立在 Lance(一种开源列式数据格式)之上,具有一些有趣的功能,使其对 AI/ML 具有吸引力。例如,LanceDB 支持显式和隐式矢量化,能够处理各种数据类型。LanceDB 与 PyTorch 和 TensorFlow 等领先的 M…

三菱人机交互GT Designer的使用(三,指示灯,数值显示与输入,字符串显示与输入,日期|时间的显示)

今天继续对GT进行学习,如有不妥,欢迎指正!!! 目录 指示灯设置 设置指示灯 位指示灯 字指示灯 数值输入,输出(二者差距不大) 数值显示与输出 数值显示(只能显示&…

【Maven】工程依赖下载失败错误解决

在使用 Maven 构建项目时,可能会发生依赖项下载错误的情况,主要原因有以下几种: 下载依赖时出现网络故障或仓库服务器宕机等原因,导致无法连接至 Maven 仓库,从而无法下载依赖。 依赖项的版本号或配置文件中的版本号错…

【计算机毕业设计】ssm+mysql+jsp实现的在线bbs论坛系统源码

项目介绍 jspssm(springspringMVCmybatis)MySQL实现的在线bbs论坛系统源码,本系统主要实现了前台用户注册登陆、浏览帖子、发布帖子、个人信息管理、消息通知管理,积分管理,后台管理功能有:友情链接管理、…

怎么设计一个简单又直观的接口?

文章目录 问题的开端为什么从问题开始?自然而来的接口 一个接口一件事情减少依赖关系使用方式要“傻” 小结 开放的接口规范是使用者和实现者之间的合约。既然是合约,就要成文、清楚、稳定。合约是好东西,它可以让代码之间的组合有规可依。但…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型,用于创造和修改图像。这个模型能够基于文本描述来生成图像,让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API,通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…

爱思唯尔的KBS——模板、投稿、返修、接收的总结

第二篇论文终于是接受了QAQ,被审稿人疯狂拖时间,KBS是真难绷啊 由于之前发布过关于爱思唯尔旗下的ESWA博客,KBS和ESWA是类似的,因此本篇博客主要说下区别以及期间碰到的各种情况,有疑问依然可以在评论区说,…

【C语言】函数

函数是什么? “函数”是我们早些年在学习数学的过程中常见的概念,简单回顾一下:比如下图中,你给函数 f(x)2*x3 一个具体的x,这个函数通过一系列的计算来返回给你一个结果(图示如下)。 这就是数学中函数的基本过程和作用。但是你…

48、激活函数 - 梯度消失和梯度爆炸

简单介绍下梯度消失和梯度爆炸,这个不是重点,但是我觉得有必要再深入了解这个概念,以及很多激活函数为什么是可以防止梯度消失的。 梯度消失和梯度爆炸实际上是在神经网络训练过程中经常会遇到的两类问题,这两类问题都与梯度有关。 什么是梯度 在神经网络训练中,梯度是指…

Final Cut 视频剪辑快速入门,小白上手视频课的制作

本文是一个快速入门教程,如果您是0视频处理基础,又想录制网课或是一些对效果要求不高的视频那么这篇教程足够使用了。 本文主要用Final Cut处理视频课,本文是笔者在制作视频课过程中逐渐摸索的,如果您想制作一些比较专业的视频&a…