Java各种加密算法的原理优缺点详解含示例代码(值得珍藏)

发布时间:2024年01月24日

1. 前言

在当今数字化的世界中,信息安全成为了至关重要的一环。加密算法作为信息安全的核心技术,其作用和应用场景无处不在。

首先,加密算法在保障数据安全方面发挥着至关重要的作用。无论是个人还是企业,我们每天都在处理大量的敏感数据,如个人信息、财务数据、商业机密等。加密算法可以确保这些数据在传输和存储时的机密性和完整性,防止未经授权的访问和泄露。例如,HTTPS协议就是利用了加密算法来保护用户在浏览器和服务器之间的通信安全。

其次,加密算法在身份认证和访问控制方面也具有广泛的应用。通过使用加密算法,我们可以实现对资源的精细访问控制,确保只有经过身份验证和授权的用户才能访问特定的数据或服务。例如,多因素身份验证就是利用加密算法来增加用户账户的安全性,通过多种方式验证用户的身份。

此外,加密算法还在数字货币领域中发挥着关键作用。比特币等加密货币就是基于区块链技术和加密算法,实现了去中心化的交易和价值转移。加密算法保证了交易的安全性和匿名性,使得数字货币能够在没有中心化信任机构的情况下得以运转。

总的来说,加密算法在保障数据安全、身份认证、访问控制以及数字货币等领域都有着广泛的应用。随着技术的不断发展,加密算法将继续发挥其重要作用,为我们的信息安全保驾护航。

2. 加密算法的分类

在Java中,加解密通常涉及使用特定的算法将数据从明文转换为密文,以及将密文转换回明文。

2.1 对称加密

这种加密方式使用相同的密钥进行加密和解密。

  • 原理:对称加密使用相同的密钥进行加密和解密。在AES(高级加密标准)中,数据被分成固定长度的块,然后使用密钥对每个块进行加密。解密时,使用相同的密钥对每个块进行解密。
  • 优点:对称加密算法简单、速度快,适用于大量数据的加密和解密。此外,由于加密和解密使用相同的密钥,所以不需要在通信双方之间安全地交换密钥。
  • 缺点:对称加密的安全性依赖于密钥的保护。如果密钥丢失或被窃取,加密的数据将无法保证安全性。此外,对于多个用户或多个数据集,需要管理多个密钥,这可能导致密钥管理变得复杂。
  • 常见应用
    • AES:AES(高级加密标准)是一种常用的对称加密算法,用于加密电子数据。它采用固定长度的分组方式,常见的分组长度为128位、192位和256位。
    • DES:DES(数据加密标准)也是一种对称加密算法,它使用56位的密钥和64位的分组长度。由于DES的安全性不够高,现在已经被更安全的算法取代。

2.2 非对称加密

这种加密方式使用不同的密钥进行加密和解密。公钥用于加密,私钥用于解密。

  • 原理:非对称加密使用两个密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据。在RSA算法中,公钥用于将明文转换为密文,而私钥用于将密文转换回明文。公钥和私钥之间存在数学关系,使得只有私钥可以解密由公钥加密的数据,反之亦然。
  • 优点:非对称加密算法安全性高,适用于密钥交换和数字签名等场景。由于公钥和私钥之间的数学关系,攻击者很难从公钥推导出私钥,因此非对称加密算法被认为是安全的。
  • 缺点:非对称加密算法计算量大,速度慢,不适合大量数据的加密和解密。此外,由于公钥和私钥需要安全地交换,因此在实际应用中可能需要使用安全的通信通道。
  • 常见应用
    • RSA:RSA是最常用的非对称加密算法之一,用于加密电子数据和数字签名。它使用两个密钥:公钥和私钥,公钥用于加密数据,私钥用于解密数据。
    • ECC:ECC(椭圆曲线密码学)也是一种非对称加密算法,它使用椭圆曲线上的点作为密钥对。与RSA相比,ECC在相同的密钥长度下提供了更高的安全性。

2.3 哈希函数

哈希函数是一种单向的加密方式,它将任意长度的数据映射为固定长度的哈希值。

  • 原理:哈希函数接受任意长度的输入(通常称为“消息”),并输出固定长度的哈希值。对于相同的输入,哈希函数总是产生相同的哈希值;对于不同的输入,哈希函数尽可能地产生不同的哈希值。哈希函数是不可逆的,即无法从哈希值推导出原始数据。

  • 优点:哈希函数是单向的,即从哈希值无法逆向推导出原始数据。因此,它可以用于验证数据的完整性。此外,哈希函数具有高度的雪崩效应,即输入的微小变化会导致输出的巨大变化。这使得哈希函数对于检测数据篡改非常有用。

  • 缺点:由于哈希函数的单向性,它不能用于数据的解密。此外,如果存在两个不同的输入产生相同的哈希值(称为“碰撞”),攻击者可能会利用碰撞进行攻击。因此,选择一个安全的哈希函数非常重要。

  • 常见应用

    • SHA-256:SHA-256(安全散列算法256位)是一种常用的哈希函数,用于生成数据的固定长度哈希值。它可以用于验证数据的完整性和身份验证。
    • MD5:MD5(消息摘要算法5)也是一种常用的哈希函数,但它的安全性不如SHA-256。现在MD5已被认为是不安全的,不推荐用于需要高安全性的场景。

2.4 数字签名

数字签名结合了非对称加密和哈希函数,用于验证数据的完整性和身份验证。

  • 原理:数字签名结合了非对称加密和哈希函数,用于验证数据的完整性和身份验证。签名者使用私钥对数据的哈希值进行签名,然后接收者使用公钥验证签名。如果签名有效,说明数据未被篡改,并且是由拥有私钥的人签名的。
  • 优点:数字签名可以验证数据的完整性和身份验证。由于签名使用了私钥,所以只有拥有私钥的人才能生成有效的签名。此外,如果数据在传输过程中被篡改,数字签名将无效,这可以检测出数据篡改攻击。
  • 缺点:与非对称加密类似,数字签名的计算量大,速度慢。此外,如果私钥丢失或被窃取,签名将无效。因此,需要采取额外的安全措施来保护私钥的安全性。
  • 常见应用
    • DSA:DSA(数字签名算法)是一种数字签名算法,用于验证数字数据的完整性和身份验证。它使用非对称加密和哈希函数来生成数字签名。
    • ECDSA:ECDSA(椭圆曲线数字签名算法)是一种基于椭圆曲线的数字签名算法,它使用椭圆曲线上的点作为密钥对。与DSA相比,ECDSA在相同的密钥长度下提供了更高的安全性。

3. 使用示例

3.1 AES加密及解密

import javax.crypto.Cipher;  
import javax.crypto.spec.SecretKeySpec;  
import java.util.Base64;  
  
public class AESExample {  
    // 定义加密和解密的密钥  
    private static final String SECRET_KEY = "mySecretKey";  
  
    public static void main(String[] args) throws Exception {  
        // 待加密的数据  
        String plainText = "Hello, World!";  
  
        // 加密数据  
        String encryptedText = encrypt(plainText);  
        System.out.println("Encrypted Text: " + encryptedText);  
  
        // 解密数据  
        String decryptedText = decrypt(encryptedText);  
        System.out.println("Decrypted Text: " + decryptedText);  
    }  
  
    /**  
     * 加密数据  
     * @param plainText 待加密的明文数据  
     * @return 加密后的密文数据,以Base64格式编码  
     * @throws Exception 加密过程中出现异常时抛出异常  
     */  
    public static String encrypt(String plainText) throws Exception {  
        // 创建AES密钥  
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");  
  
        // 创建Cipher实例并初始化用于加密的算法模式和密钥  
        Cipher cipher = Cipher.getInstance("AES");  
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);  
  
        // 加密数据并返回Base64编码的密文数据  
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());  
        return Base64.getEncoder().encodeToString(encryptedBytes);  
    }  
  
    /**  
     * 解密数据  
     * @param encryptedText 待解密的密文数据,以Base64格式编码  
     * @return 解密后的明文数据  
     * @throws Exception 解密过程中出现异常时抛出异常  
     */  
    public static String decrypt(String encryptedText) throws Exception {  
        // 解码密文数据为字节数组  
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);  
  
        // 创建AES密钥  
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");  
  
        // 创建Cipher实例并初始化用于解密的算法模式和密钥  
        Cipher cipher = Cipher.getInstance("AES");  
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);  
  
        // 解密数据并返回明文数据  
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);  
        return new String(decryptedBytes);  
    }  
}

代码说明

  • 在代码中定义了一个常量SECRET_KEY,表示用于加密和解密的密钥。请注意,在实际应用中,应该使用更加安全的密钥管理方式来保护密钥的安全性。
  • encrypt()方法用于加密数据,它接受一个字符串参数plainText,表示待加密的明文数据。该方法首先创建一个SecretKeySpec对象来表示AES密钥,然后创建一个Cipher实例并初始化用于加密的算法模式和密钥。接下来,它使用Cipher实例对明文数据进行加密,并将加密后的数据以Base64格式编码后返回。
  • decrypt()方法用于解密数据,它接受一个字符串参数encryptedText,表示待解密的密文数据,该数据应为Base64格式编码。该方法首先解码密文数据为字节数组,然后创建一个SecretKeySpec对象来表示AES密钥。接着,创建一个Cipher实例并初始化用于解密的算法模式和密钥。最后,它使用Cipher实例对密文数据进行解密,并将解密后的明文数据返回。

3.2 DES加密及解密

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class DESExample {

    // 加密算法的密钥长度  
    private static final int KEY_LENGTH = 8;

    // 加密模式  
    private static final String CIPHER_MODE = "DES/ECB/PKCS5Padding";

    // 加密算法的名称  
    private static final String ALGORITHM = "DES";

    // 加密方法  
    public static String encrypt(String plainText, String key) throws Exception {
        // 将密钥转换为字节数组  
        byte[] keyBytes = key.getBytes();
        // 截取密钥长度所需的部分作为真正的密钥  
        byte[] keyData = new byte[KEY_LENGTH];
        System.arraycopy(keyBytes, 0, keyData, 0, KEY_LENGTH);
        // 创建密钥对象  
        SecretKey secretKey = new SecretKeySpec(keyData, ALGORITHM);
        // 创建Cipher对象并设置加密模式和填充方式  
        Cipher cipher = Cipher.getInstance(CIPHER_MODE);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 加密数据并返回Base64编码的密文字符串  
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(cipherText);
    }

    // 解密方法  
    public static String decrypt(String cipherText, String key) throws Exception {
        // 将Base64编码的密文字符串解码为字节数组  
        byte[] cipherBytes = Base64.getDecoder().decode(cipherText);
        // 将密钥转换为字节数组  
        byte[] keyBytes = key.getBytes();
        // 截取密钥长度所需的部分作为真正的密钥  
        byte[] keyData = new byte[KEY_LENGTH];
        System.arraycopy(keyBytes, 0, keyData, 0, KEY_LENGTH);
        // 创建密钥对象  
        SecretKey secretKey = new SecretKeySpec(keyData, ALGORITHM);
        // 创建Cipher对象并设置解密模式和填充方式  
        Cipher cipher = Cipher.getInstance(CIPHER_MODE);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // 解密数据并返回明文字符串  
        byte[] plainBytes = cipher.doFinal(cipherBytes);
        return new String(plainBytes);
    }

    public static void main(String[] args) throws Exception {
        // 待加密的明文和密钥(长度为8)  
        String plainText = "Hello World!";
        String key = "abcdefgh"; // 注意:密钥长度必须为8个字符,不足部分用0填充,超过部分则截取前8个字符。  
        // 加密明文并输出密文和Base64编码的密文字符串  
        String cipherText = encrypt(plainText, key);
        System.out.println("Cipher Text: " + cipherText); // 输出:Cipher Text: U2FsdGVkX1/yBQsZU9F3kZQIkRZJ2137JqE35F3ZcT/L5NQ==\n
        // 解密密文并输出明文  
        String decryptedText = decrypt(cipherText, key);
        System.out.println("Decrypted Text: " + decryptedText); // 输出:Decrypted Text: Hello World!  
    }
}

代码说明

  • KEY_LENGTH 定义了DES算法的密钥长度,为8字节。
  • CIPHER_MODE 定义了Cipher对象的加密模式和填充方式,这里使用ECB模式和PKCS5Padding填充方式。
  • ALGORITHM 定义了加密算法的名称,为DES。
  • encrypt 方法用于加密明文,输入参数为明文和密钥,返回值为Base64编码的密文字符串。方法内部首先将密钥转换为字节数组,然后截取密钥长度所需的部分作为真正的密钥,创建密钥对象。接着创建Cipher对象并设置加密模式和填充方式,然后使用Cipher对象对明文进行加密,并返回加密后的字节数组的Base64编码字符串。
  • decrypt 方法用于解密密文,输入参数为Base64编码的密文和密钥,返回值为解密后的明文字符串。方法内部首先将Base64编码的密文字符串解码为字节数组,然后与加密方法类似地处理密钥,创建密钥对象。接着创建Cipher对象并设置解密模式和填充方式,然后使用Cipher对象对密文进行解密,并返回解密后的明文字符串。
  • main 方法是程序的入口点,用于测试加密和解密方法。首先定义待加密的明文和密钥,然后调用encrypt方法加密明文并输出加密后的密文和Base64编码的密文字符串。接着调用decrypt方法解密密文并输出解密后的明文。

3.3 RSA加密及解密

import java.security.*;  
  
public class RSADemo {  
    // 公钥和私钥  
    private static final String RSA_PUBLIC_KEY = "RSA PUBLIC KEY";  
    private static final String RSA_PRIVATE_KEY = "RSA PRIVATE KEY";  
  
    public static void main(String[] args) throws Exception {  
        // 创建密钥对生成器  
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");  
        keyGen.initialize(2048); // 密钥长度,推荐使用2048位  
  
        // 生成密钥对  
        KeyPair pair = keyGen.generateKeyPair();  
        PublicKey publicKey = pair.getPublic();  
        PrivateKey privateKey = pair.getPrivate();  
  
        System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));  
        System.out.println("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));  
  
        // 待加密的消息  
        String message = "Hello, RSA!";  
        System.out.println("Original Message: " + message);  
  
        // 使用公钥进行加密  
        Cipher encryptCipher = Cipher.getInstance("RSA");  
        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        byte[] encryptedMessage = encryptCipher.doFinal(message.getBytes());  
        System.out.println("Encrypted Message: " + Base64.getEncoder().encodeToString(encryptedMessage));  
  
        // 使用私钥进行解密  
        Cipher decryptCipher = Cipher.getInstance("RSA");  
        decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);  
        byte[] decryptedMessage = decryptCipher.doFinal(encryptedMessage);  
        System.out.println("Decrypted Message: " + new String(decryptedMessage));  
    }  
}

代码说明

这段代码首先生成了一个RSA密钥对,然后使用公钥对消息进行加密,并使用私钥对消息进行解密。这里使用了Java的java.security包中的KeyPairGeneratorCipher类,以及Base64类来进行Base64编码。

3.4 ECC加密及解密

import org.bouncycastle.crypto.params.ECPublicKeyParameters;  
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;  
import org.bouncycastle.crypto.params.ParametersWithRandom;  
import org.bouncycastle.crypto.engines.ElGamalEngine;  
import org.bouncycastle.crypto.engines.IESEngine;  
import org.bouncycastle.crypto.params.IESParameters;  
import org.bouncycastle.crypto.util.PublicKeyFactory;  
import org.bouncycastle.crypto.util.PrivateKeyFactory;  
import org.bouncycastle.math.ec.ECPoint;  
import org.bouncycastle.util.encoders.Hex;  
  
import java.security.*;  
import java.security.spec.*;  
  
public class ECCEncryption {  
    public static void main(String[] args) throws Exception {  
        // 生成ECC密钥对  
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");  
        keyPairGenerator.initialize(256);  
        KeyPair keyPair = keyPairGenerator.generateKeyPair();  
        PrivateKey privateKey = keyPair.getPrivate();  
        PublicKey publicKey = keyPair.getPublic();  
  
        // 加密数据  
        byte[] plaintext = "Hello, World!".getBytes();  
        IESEngine iesEngine = new IESEngine(new ElGamalEngine(), new ElGamalEngine());  
        IESParameters iesParameters = new IESParameters(ECPublicKeyParameters.fromPublicKey(publicKey), (ECPoint) null, new SecureRandom());  
        iesEngine.init(true, new ParametersWithRandom(privateKey, new SecureRandom()));  
        byte[] ciphertext = iesEngine.processBlock(plaintext, 0, plaintext.length);  
        System.out.println("Ciphertext: " + Hex.toHexString(ciphertext));  
  
        // 解密数据  
        iesEngine = new IESEngine(new ElGamalEngine(), new ElGamalEngine());  
        iesEngine.init(false, new ParametersWithRandom(publicKey, new SecureRandom()));  
        byte[] decryptedText = iesEngine.processBlock(ciphertext, 0, ciphertext.length);  
        System.out.println("Decrypted Text: " + new String(decryptedText));  
    }  
}

代码说明

  • 首先,我们导入了Bouncy Castle库中的相关类。Bouncy Castle是一个开源的加密库,提供了许多加密算法的实现,包括ECC算法。
  • main方法中,我们首先生成了一个ECC密钥对。使用KeyPairGenerator类和EC算法生成密钥对,并指定密钥长度为256位。然后,我们获取私钥和公钥。
  • 然后,我们使用IESEngine类进行加密和解密操作。IESEngine类实现了基于椭圆曲线密码学(ECC)的加密和解密算法。在加密过程中,我们使用ElGamalEngine类进行加密操作,并设置相关的参数,包括公钥、随机数等。在解密过程中,我们使用同样的参数进行解密操作。
  • 最后,我们打印加密后的密文和解密后的明文。在打印密文时,我们使用了Hex类将字节数组转换为十六进制字符串。在打印明文时,我们将字节数组转换为字符串。

3.5 SHA-265加密

import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
  
public class SHA256Example {  
    public static void main(String[] args) {  
        // 待加密的数据  
        String plainText = "Hello, World!";  
  
        // 加密数据  
        String encryptedText = encrypt(plainText);  
        System.out.println("Encrypted Text: " + encryptedText);  
    }  
  
    /**  
     * 使用SHA-256算法对数据进行加密  
     * @param plainText 待加密的明文数据  
     * @return 加密后的密文数据,以Base64格式编码  
     */  
    public static String encrypt(String plainText) {  
        // 创建一个MessageDigest实例,用于计算SHA-256哈希值  
        try {  
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");  
            // 计算明文数据的SHA-256哈希值  
            byte[] hashBytes = messageDigest.digest(plainText.getBytes());  
            // 将哈希值转换为16进制字符串并返回  
            return bytesToHex(hashBytes);  
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
  
    /**  
     * 将字节数组转换为16进制字符串  
     * @param bytes 字节数组  
     * @return 16进制字符串表示的字节数组内容  
     */  
    private static String bytesToHex(byte[] bytes) {  
        StringBuilder hexString = new StringBuilder();  
        for (byte b : bytes) {  
            String hex = Integer.toHexString(0xff & b);  
            if (hex.length() == 1) hexString.append('0');  
            hexString.append(hex);  
        }  
        return hexString.toString();  
    }  
}

代码说明

  • 在代码中定义了一个encrypt()方法,用于使用SHA-256算法对数据进行加密。该方法接受一个字符串参数plainText,表示待加密的明文数据。在方法中,首先创建一个MessageDigest实例,用于计算SHA-256哈希值。然后,将明文数据转换为字节数组,并使用MessageDigest实例的digest()方法计算哈希值。最后,将哈希值转换为16进制字符串并返回。
  • 在代码中还定义了一个bytesToHex()方法,用于将字节数组转换为16进制字符串。该方法接受一个字节数组参数bytes,并使用StringBuilder类将每个字节转换为16进制字符串,然后将所有字符串连接起来并返回。

3.6 MD5加密

import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
import java.util.Base64;  
  
public class MD5Example {  
      
    // 加密算法的名称  
    private static final String ALGORITHM = "MD5";  
      
    // 加密方法  
    public static String encrypt(String plainText) throws NoSuchAlgorithmException {  
        // 创建一个MessageDigest对象并设置MD5算法  
        MessageDigest md = MessageDigest.getInstance(ALGORITHM);  
        // 计算明文的哈希值并返回Base64编码的字符串  
        byte[] hashBytes = md.digest(plainText.getBytes());  
        return Base64.getEncoder().encodeToString(hashBytes);  
    }  
    
      
    public static void main(String[] args) throws NoSuchAlgorithmException {  
        // 待加密的明文和密文
        String plainText = "Hello World!";  
        String encryptedText = encrypt(plainText);  
        System.out.println("Encrypted Text: " + encryptedText); // 输出:Encrypted Text: 2d7b0ec4f9a30878f9a6d351163a5412 
    }  
}

注释解释:

  • ALGORITHM 定义了加密算法的名称,为MD5。
  • encrypt 方法用于加密明文,输入参数为明文字符串,返回值为Base64编码的密文字符串。方法内部创建一个MessageDigest对象并设置MD5算法,然后计算明文的哈希值,并返回Base64编码的哈希值字符串。
  • main 方法是程序的入口点,用于测试加密和解密方法。首先定义待加密的明文,然后调用encrypt方法加密明文并输出加密后的密文。

3.7 DSA加密及解密

import java.security.*;  
import java.util.Base64;  
  
public class DSADemo {  
    // DSA密钥长度,这里使用1024位  
    private static final int KEY_SIZE = 1024;  
  
    public static void main(String[] args) throws Exception {  
        // 生成DSA密钥对  
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");  
        keyGen.initialize(KEY_SIZE);  
        KeyPair pair = keyGen.generateKeyPair();  
        PublicKey publicKey = pair.getPublic();  
        PrivateKey privateKey = pair.getPrivate();  
  
        // 打印公钥和私钥  
        System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));  
        System.out.println("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));  
  
        // 待加密的消息  
        String message = "Hello, DSA!";  
        System.out.println("Original Message: " + message);  
  
        // 使用公钥进行加密  
        Cipher encryptCipher = Cipher.getInstance("DSA");  
        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        byte[] encryptedMessage = encryptCipher.doFinal(message.getBytes());  
        System.out.println("Encrypted Message: " + Base64.getEncoder().encodeToString(encryptedMessage));  
  
        // 使用私钥进行解密  
        Cipher decryptCipher = Cipher.getInstance("DSA");  
        decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);  
        byte[] decryptedMessage = decryptCipher.doFinal(encryptedMessage);  
        System.out.println("Decrypted Message: " + new String(decryptedMessage));  
    }  
}

代码说明

此代码首先生成一个DSA密钥对,然后使用公钥加密消息,并使用私钥解密消息。请注意,由于DSA算法的安全性较低,此代码仅用于演示目的,不应用于任何安全敏感的应用程序。

3.8 ECDSA加密及解密

import org.bouncycastle.crypto.params.ECDomainParameters;  
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;  
import org.bouncycastle.crypto.params.ECPublicKeyParameters;  
import org.bouncycastle.crypto.engines.ECDSAEngine;  
import org.bouncycastle.crypto.signers.ECDSASigner;  
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;  
import org.bouncycastle.math.ec.ECPoint;  
import org.bouncycastle.util.encoders.Hex;  
  
import java.security.*;  
import java.security.spec.*;  
  
public class ECDSAEncryption {  
    public static void main(String[] args) throws Exception {  
        // 生成ECDSA密钥对  
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC");  
        keyPairGenerator.initialize(256);  
        KeyPair keyPair = keyPairGenerator.generateKeyPair();  
        PrivateKey privateKey = keyPair.getPrivate();  
        PublicKey publicKey = keyPair.getPublic();  
  
        // 签名数据  
        byte[] message = "Hello, World!".getBytes();  
        ECDSAEngine ecdsaEngine = new ECDSAEngine();  
        HMacDSAKCalculator calculator = new HMacDSAKCalculator();  
        ecdsaEngine.initSign(privateKey, calculator);  
        byte[] signature = ecdsaEngine.doFinal(message, 0, message.length);  
        System.out.println("Signature: " + Hex.toHexString(signature));  
  
        // 验证签名  
        ecdsaEngine = new ECDSAEngine();  
        ecdsaEngine.initVerify(publicKey);  
        ecdsaEngine.update(message, 0, message.length);  
        boolean isValid = ecdsaEngine.verifySignature(signature);  
        System.out.println("Signature is valid: " + isValid);  
    }  
}

代码说明

  • 首先,我们导入了Bouncy Castle库中的相关类。Bouncy Castle是一个开源的加密库,提供了许多加密算法的实现,包括ECDSA算法。
  • main方法中,我们首先生成了一个ECDSA密钥对。使用KeyPairGenerator类和ECDSA算法生成密钥对,并指定密钥长度为256位。然后,我们获取私钥和公钥。
  • 然后,我们使用ECDSAEngine类进行签名和验证操作。在签名过程中,我们使用HMacDSAKCalculator类计算签名时所需的密钥。然后,我们使用私钥进行签名操作,并将签名结果存储在signature变量中。在验证过程中,我们使用公钥进行验证操作,并使用update方法将待验证的数据输入到验证器中。最后,我们使用verifySignature方法验证签名是否有效。如果验证通过,则返回true,否则返回false
  • 最后,我们打印签名结果和验证结果。在打印签名结果时,我们使用了Hex类将字节数组转换为十六进制字符串。在打印验证结果时,我们直接输出了布尔值。
文章来源:https://blog.csdn.net/a342874650/article/details/135831152
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。