加密与解密

加密与解密

一、概述

1、对称加密

对称加密,就是加密和解密使用同一个密钥。(密钥的保密性至关重要)

  • 常见的有 AES、DES、3DES、Blowfish 等

在这里插入图片描述

2、非对称加密

非对称加密,使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密。(公钥可以公开,而私钥必须保密)

  • 常见的有 RSA、DSA、ECC 等。

在这里插入图片描述

3、哈希加密

哈希加密,用于将 任意长度的数据 转换为 固定长度的输出,通常称为哈希值或摘要。

  • 常见的有 MD5、SHA-1、SHA-256。

哈希加密的特点:

  • 不可逆:无法从哈希值反推出原始数据。
  • 固定长度:无论输入数据的大小,哈希值的长度是固定的。
  • 唯一性:相同的输入总是产生相同的哈希值。

理想情况下,不同的输入数据应产生不同的哈希值(尽管 MD5 和 SHA-1 存在碰撞漏洞)。

4、盐值

盐值(Salt)是一个随机数据,和原数据结合后进行哈希,用于增强密码存储安全性。

  • 主要目的是防止彩虹表攻击(通过预计算的哈希表来快速破解密码)
  • 加盐后,即使两个用户的密码相同,最终的哈希结果也会不同。

假设用户的密码是 123456,生成的盐值是 random_salt,哈希过程如下:

hashed_password = hash(random_salt + 123456)

存储时,数据库中会保存 random_salthashed_password

5、小结

  • 对称加密:同一个密钥,加密和解密速度快,适合快速加密大量数据,但密钥管理难度高。
  • 非对称加密:一对密钥(公钥和私钥),安全性更高,但速度相对较慢。
  • 哈希加密:不可逆,无法解密出原始数据,一般用于数据的校验,例如:密码。

这三种加密方式各有优缺点,通常在实际应用中会结合使用,以实现更高的安全性。

例如,在 HTTPS 中,使用 非对称加密 安全地交换 对称加密 的密钥,然后使用 对称加密 进行数据传输。

二、AES 对称加密

import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class AESExample {
    public static void main(String[] args) throws Exception {
        String plainText = "Hello, World!";
        SecretKey secretKey = generateAESKey();

        String encryptedText = encrypt(plainText, secretKey);
        String decryptedText = decrypt(encryptedText, secretKey);

        System.out.println("Original: " + plainText);
        System.out.println("Encrypted: " + encryptedText);
        System.out.println("Decrypted: " + decryptedText);
    }

    public static SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128); // or 256
        return keyGenerator.generateKey();
    }

    public static String encrypt(String plainText, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

三、RSA 非对称加密

1、加密与解密

  • A 生成公钥和私钥,私钥自己保留,公钥任何人可以获取。
  • B 拿到公钥,将数据通过公钥加密,然后将密文传给 A。
  • A 收到密文,通过私钥解密,得到明文。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSAExample {
    public static void main(String[] args) throws Exception {
        String plainText = "Hello, RSA!";
        KeyPair keyPair = generateRSAKeyPair();

        String encryptedText = encrypt(plainText, keyPair.getPublic());
        String decryptedText = decrypt(encryptedText, keyPair.getPrivate());

        System.out.println("Original: " + plainText);
        System.out.println("Encrypted: " + encryptedText);
        System.out.println("Decrypted: " + decryptedText);
    }

    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }

    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

2、签名与验签

验签是指通过私钥对消息进行签名,使得消息无法篡改和伪造。

  • A 生成公钥和私钥,私钥自己保留,公钥任何人可以获取。
  • A 使用私钥对消息加签,并将加签后的消息传给 B。
  • B 通过公钥验签,如果返回是true,则说明消息是A发过来的且未被篡改。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;

public class RSASignatureExample {

    public static void main(String[] args) throws Exception {
        String message = "这是需要签名的消息";
        KeyPair keyPair = generateRSAKeyPair();

        // 数字签名
        String signature = signMessage(keyPair.getPrivate(), message);
        System.out.println("签名: " + signature);

        // 验证签名
        boolean isValid = verifySignature(keyPair.getPublic(), message, signature);
        System.out.println("签名有效性: " + isValid);
    }

    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }

    // 签名方法
    public static String signMessage(PrivateKey privateKey, String message) throws Exception {
        Signature rsa = Signature.getInstance("SHA256withRSA");
        rsa.initSign(privateKey);
        rsa.update(message.getBytes());
        byte[] signature = rsa.sign();
        return Base64.getEncoder().encodeToString(signature);
    }

    // 验证签名方法
    public static boolean verifySignature(PublicKey publicKey, String message, String signature) throws Exception {
        Signature rsa = Signature.getInstance("SHA256withRSA");
        rsa.initVerify(publicKey);
        rsa.update(message.getBytes());
        byte[] signatureBytes = Base64.getDecoder().decode(signature);
        return rsa.verify(signatureBytes);
    }

}

四、MD5 哈希加密

常用于将密码加密后保存到数据库。用户输入密码后先 MD5 计算,再和数据库里的 MD5密码 比较。

import java.security.MessageDigest;

public class MD5Example {

    public static void main(String[] args) throws Exception {
        String text = "Hello, MD5!";
        String hash = md5(text);
        System.out.println("MD5 Hash: " + hash);
    }

    public static String md5(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(input.getBytes());
        return byteToHex(digest);
    }

    private static String byteToHex(byte[] digest) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : digest) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
    
}

五、SHA 哈希加密

和 MD5 类似的信息摘要算法,但是它比 MD5 更加安全。

import java.security.MessageDigest;

public class SHAExample {

    public static void main(String[] args) throws Exception {
        String text = "Hello, SHA-256!";
        String hash = sha256(text);
        System.out.println("SHA-256 Hash: " + hash);
    }

    // sha-1加密(160位,20字节,40个十六进制字符)
    public static String sha1(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digest = md.digest(input.getBytes());
        return byteToHex(digest);
    }

    // sha-256加密(256位,32字节,64个十六进制字符)
    public static String sha256(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(input.getBytes());
        return byteToHex(digest);
    }

    // sha-512加密(512位,64字节,128个十六进制字符)
    public static String sha512(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-512");
        byte[] digest = md.digest(input.getBytes());
        return byteToHex(digest);
    }

    private static String byteToHex(byte[] digest) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : digest) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

}

由于安全性问题,MD5 和 SHA-1 不再被推荐用于安全相关的用途。SHA-256 和 SHA-512 是目前较为安全的选择。

对于简单的完整性检查,可以考虑使用 MD5,但需谨慎评估其风险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值