对称加密和非对称加密

66 阅读2分钟

引用:www.cnblogs.com/Brickert/p/… 对称加密即加密和解密用的都是同一个密钥。非对称加密即加密和解密各自一套密钥。

非对称加密的java示例:

在Java中使用RSA非对称加密主要通过java.security包和javax.crypto包实现。以下是详细说明:

1. 生成RSA密钥对

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;

public class RSAKeyGenerator {
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        // 创建密钥对生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥长度,通常为1024或2048位
        keyPairGenerator.initialize(2048);
        // 生成密钥对
        return keyPairGenerator.generateKeyPair();
    }
}

2. 获取公钥和私钥

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

public class RSAKeyHandler {
    public static PublicKey getPublicKey(KeyPair keyPair) {
        return keyPair.getPublic();
    }
    
    public static PrivateKey getPrivateKey(KeyPair keyPair) {
        return keyPair.getPrivate();
    }
}

3. 使用公钥加密

import javax.crypto.Cipher;
import java.security.PublicKey;
import java.util.Base64;

public class RSAEncryption {
    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        // 获取Cipher实例
        Cipher cipher = Cipher.getInstance("RSA");
        // 初始化为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 执行加密
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        // 使用Base64编码便于传输
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
}

4. 使用私钥解密

import javax.crypto.Cipher;
import java.security.PrivateKey;
import java.util.Base64;

public class RSADecryption {
    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        // 获取Cipher实例
        Cipher cipher = Cipher.getInstance("RSA");
        // 初始化为解密模式
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        // Base64解码
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);
        // 执行解密
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes);
    }
}

5. 完整示例

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import java.util.Base64;

public class RSADemo {
    public static void main(String[] args) throws Exception {
        // 生成密钥对
        KeyPair keyPair = RSAKeyGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        // 原始数据
        String originalText = "Hello RSA Encryption!";
        System.out.println("Original Text: " + originalText);
        
        // 使用公钥加密
        String encryptedText = RSAEncryption.encrypt(originalText, publicKey);
        System.out.println("Encrypted Text: " + encryptedText);
        
        // 使用私钥解密
        String decryptedText = RSADecryption.decrypt(encryptedText, privateKey);
        System.out.println("Decrypted Text: " + decryptedText);
    }
}

6. 密钥存储和读取

保存密钥到文件

import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class KeyStorage {
    // 保存公钥
    public static void savePublicKey(PublicKey publicKey, String filename) throws IOException {
        byte[] publicKeyBytes = publicKey.getEncoded();
        try (FileOutputStream fos = new FileOutputStream(filename)) {
            fos.write(publicKeyBytes);
        }
    }
    
    // 保存私钥
    public static void savePrivateKey(PrivateKey privateKey, String filename) throws IOException {
        byte[] privateKeyBytes = privateKey.getEncoded();
        try (FileOutputStream fos = new FileOutputStream(filename)) {
            fos.write(privateKeyBytes);
        }
    }
}

注意事项

  1. 数据长度限制:RSA加密有长度限制,通常为密钥长度/8 - 11字节
  2. 性能考虑:RSA加密速度较慢,通常用于加密小量数据或对称密钥
  3. 填充方式:实际应用中应指定填充方式,如RSA/ECB/PKCS1Padding
  4. 密钥管理:私钥必须安全保存,不能泄露

通过以上步骤,可以在Java中实现完整的RSA非对称加密功能。