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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 【Java技术专题】「入门到精通系列」深入探索Java技术中常用到的六种加密技术和实现

背景介绍

重点记住现代密码学的柯克霍夫原则:数据安全取决于密钥而不是算法的保密。即使密码系统的细节已经公开,只要密钥保密,系统依然可以保持安全。本文介绍了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的开源项目,其中包含了常用的编码和加密方式的实现,可以在其官方网站(commons.apache.org/proper/comm…
  3. Bouncy Castle(BC):Bouncy Castle是一个加密算法提供方,提供了丰富的密码学功能和算法实现,可以在其官方网站(www.bouncycastle.org/java.html)获…

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

加密算法介绍

Base64算法

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

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

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

java

复制代码

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语言):

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语言):

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位的密钥进行加密,生成密文组。

java

复制代码

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 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

java

复制代码

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 倍。

java

复制代码

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

java

复制代码

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 算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

java

复制代码

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所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成“一致”的、可以共享的密钥。也就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。

java

复制代码

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算法通常用于密钥协商,生成的共享密钥可以作为对称加密算法的密钥来进行加密和解密操作。

相关文章
|
4天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
30 11
|
13天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
50 7
|
25天前
|
存储 安全 数据安全/隐私保护
Codota的数据加密技术包括静态数据加密和传输中的数据加密
Codota的数据加密技术包括静态数据加密和传输中的数据加密
46 4
|
18天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
38 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
14天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
14天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
1月前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
27天前
|
Java 程序员 数据库连接
Java中的异常处理:从入门到精通
在Java编程的海洋中,异常处理是一艘不可或缺的救生艇。它不仅保护你的代码免受错误数据的侵袭,还能确保用户体验的平稳航行。本文将带你领略异常处理的风浪,让你学会如何在Java中捕捉、处理和预防异常,从而成为一名真正的Java航海家。