Java实现AES,DES,RSA加密

Java的Cipher类

Cipher类提供了加密和解密的功能。

Cipher类可以完成aes,des,des3和rsa等加密方式

代码替换

//sun包不推荐使用建议换成java.util.Base64

import sun.misc.BASE64Decoder;
--->
import java.util.Base64;

// 加密
Base64.getEncoder().encodeToString(encrypted);
// 解密
Base64.getDecoder().decode(sSrc);

AES加密算法

介绍

这个标准用来替代原先的DES,AES加密过程涉及到4种操作,分别是字节替代、行移位、列混淆和轮密钥加。解密过程分别为对应的逆操作。由于每一步操作都是可逆的,按照相反的顺序进行解密即可恢复明文。加解密中每轮的密钥分别由初始密钥扩展得到。算法中16个字节的明文、密文和轮密钥都以一个4x4的矩阵表示。

特点

运算速度快,安全性高,资源消耗少

实现1

package utils;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * @Description: 加密
 * @Author zhou
 * @Date 2024/5/29 - 14:38
 */
public class AESUtil {

    public static final String sKey = "111;AAAA1234++==";

    /**
     * 加密
     * @param crypt 输入密码
     * @return 返回加密数据
     */
    public static String encrypt(Object crypt){
        String sSrc = String.valueOf(crypt);
        byte[] raw = sKey.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = null;//"算法/模式/补码方式"
        byte[] encrypted = new byte[0];
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
            encrypted = cipher.doFinal(sSrc.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new BASE64Encoder().encode(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。
    }

    /**
     * 解密
     * @param crypt 需要解密的字符串
     * @return 解密后的数据
     */
    public static String decrypt(Object crypt){
        String sSrc = String.valueOf(crypt);
        // 判断Key是否正确
        byte[] raw = sKey.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = null;//"算法/模式/补码方式"
        byte[] original = new byte[0];
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//先用base64解密
            original = cipher.doFinal(encrypted1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(original,StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        // 需要加密的字串
        String cSrc = "123456";
        // 加密
        String enString = encrypt(cSrc);
        System.out.println("加密后的字串是:" + enString);

        // 解密
        String DeString = decrypt(enString);
        System.out.println("解密后的字串是:" + DeString);
    }
}

实现2

package com.demo;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * AES 本身就是为了取代 DES 的,AES 具有更好的 安全性、效率 和 灵活性
 */
public class AESUtils {

    /*
     * 加密(对外暴露)
     */
    public static String encryptData(String privateKey, String content) throws Exception {
        KeyGenerator keygen = getKeyGenerator(privateKey);
        SecretKey key = new SecretKeySpec(keygen.generateKey().getEncoded(), "AES");
        return Base64.getEncoder().encodeToString(encrypt(key, content.getBytes("UTF-8")));
    }

    /*
     * 解密(对外暴露)
     */
    public static String decryptData(String privateKey, String content) throws Exception {
        KeyGenerator keygen = getKeyGenerator(privateKey);
        SecretKey key = new SecretKeySpec(keygen.generateKey().getEncoded(), "AES");
        return new String(decrypt(key, Base64.getDecoder().decode(content)), "UTF-8");
    }

    private static KeyGenerator getKeyGenerator(String privateKey) throws NoSuchAlgorithmException {
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(privateKey.getBytes());
        keygen.init(128, secureRandom);
        return keygen;
    }

    private static byte[] encrypt(Key key, byte[] srcBytes) {
        if (key != null) {
            try {
                // Cipher负责完成加密或解密工作,基于AES
                Cipher cipher = Cipher.getInstance("AES");
                // 对Cipher对象进行初始化
                cipher.init(Cipher.ENCRYPT_MODE, key);
                // 加密,保存并返回
                return cipher.doFinal(srcBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static byte[] decrypt(Key key, byte[] encBytes) {
        if (key != null) {
            try {
                Cipher cipher = Cipher.getInstance("AES");
                //对Cipher对象进行初始化
                cipher.init(Cipher.DECRYPT_MODE, key);
                //解密
                return cipher.doFinal(encBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    public static void main(String[] args) throws Exception {
        String privateKey = "ABC";
        String content = "ASD456";
        String m = encryptData(privateKey, content);
        System.out.println("根据私钥:" + privateKey + ",加密后的密文是:" + m);
        System.out.println("根据私钥:" + privateKey + ",解密后的明文是:" + decryptData(privateKey, m));
    }

}

DES加密算法

介绍

DES是对称性加密里常见的一种,是一种使用秘钥加密的块算法。秘钥长度是64位(bit), 超过位数秘钥被忽略。所谓对称性加密,加密和解密秘钥相同。对称性加密一般会按照固定长度,把待加密字符串分成块。不足一整块或者刚好最后有特殊填充字符。

常见的填充模式有:'pkcs5'、'pkcs7'、'iso10126'、'ansix923'、'zero' 类型,包括DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。

特点

分组比较短、秘钥太短、密码生命周期短、运算速度较慢。

实现

package com.demo;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;


public class DESUtils {

    private static Key key;
    private static final String PRIVATE_KEY = "ABC";

    static {
        try {
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(PRIVATE_KEY.getBytes());
            generator.init(secureRandom);
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密,返回BASE64的加密字符串
     * @param str
     * @return
     */
    public static String getEncryptString(String str) throws Exception {
        byte[] strBytes = str.getBytes("UTF-8");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptStrBytes = cipher.doFinal(strBytes);
        return Base64.getEncoder().encodeToString(encryptStrBytes);
    }

    /**
     * 对BASE64加密字符串进行解密
     * @param str
     * @return
     */
    public static String getDecryptString(String str) throws Exception {
        byte[] strBytes = Base64.getDecoder().decode(str);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] encryptStrBytes = cipher.doFinal(strBytes);
        return new String(encryptStrBytes, "UTF-8");
    }

    public static void main(String[] args) throws Exception {
        String name = "catdog";
        String password = "Cat<%1?2>Dog";
        String encryname = getEncryptString(name);
        String encrypassword = getEncryptString(password);
        System.out.println("加密:" + encryname);
        System.out.println("加密:" + encrypassword);

        System.out.println("解密:" + getDecryptString(encryname));
        System.out.println("解密:" + getDecryptString(encrypassword));
    }
}

RSA加密算法

介绍

RSA加密算法是一种非对称加密算法,这种算法非常可靠,密钥越长,它就越难破解。

特点

  • 不需要进行密钥传递,提高了安全性

  • 可以进行数字签名认证

  • 加密解密效率不高,一般只适用于处理小量数据(如:密钥)

  • 容易遭受小指数攻击

实现

package com.demo;

import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一。RSA 是第一个能同时用于 加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已被 ISO 推荐为公钥数据加密标准。
 */
public class RSAUtils {

    /**
     * 加密(对外暴露)
     * 如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。
     * 如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。
     *
     * @param keyStr
     * @param data
     * @return
     * @throws Exception
     */
    public static String encryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {
        if (StringUtils.isEmpty(keyStr)) {
            return "";
        }
        return encryptBASE64(encrypt(getKey(keyStr, isPublicKey), data.getBytes()));
    }

    /**
     * 解密(对外暴露)
     * 如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。
     * 如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。
     *
     * @param keyStr
     * @param data
     * @return
     * @throws Exception
     */
    public static String decryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {
        if (StringUtils.isEmpty(keyStr)) {
            return "";
        }
        return new String(decrypt(getKey(keyStr, isPublicKey), decryptBASE64(data)), "UTF-8");
    }

    /**
     * 加密
     *
     * @param key
     * @param srcBytes
     * @return
     */
    private static byte[] encrypt(Key key, byte[] srcBytes) {
        if (key != null) {
            try {
                //Cipher负责完成加密或解密工作,基于RSA
                Cipher cipher = Cipher.getInstance("RSA");
                //对Cipher对象进行初始化
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //加密,并返回
                return cipher.doFinal(srcBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 解密
     *
     * @param key
     * @param encBytes
     * @return
     */
    private static byte[] decrypt(Key key, byte[] encBytes) {
        if (key != null) {
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                //对Cipher对象进行初始化
                cipher.init(Cipher.DECRYPT_MODE, key);
                //解密并返回结果
                return cipher.doFinal(encBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据key获取公有或者私有key对象
     *
     * @param keyStr
     * @param isPublicKey
     * @return
     * @throws Exception
     */
    private static Key getKey(String keyStr, Boolean isPublicKey) throws Exception {
        if (isPublicKey) {
            return getPublicKey(keyStr);
        } else {
            return getPrivateKey(keyStr);
        }
    }

    /**
     * 根据公有key获取公有key对象
     *
     * @param key
     * @return
     * @throws Exception
     */
    private static RSAPublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPublicKey) keyFactory.generatePublic(keySpec);
    }

    /**
     * 根据私有key获取私有对象
     *
     * @param key
     * @return
     * @throws Exception
     */
    private static RSAPrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
    }

    /**
     * 获取公有/私有Key
     *
     * @return
     */
    private static KeyPair getRSAKey() {
        KeyPair keyPair = null;
        try {
            //生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            //初始化密钥对生成器,密钥大小为1024位
            keyPairGen.initialize(1024);
            //生成一个密钥对,保存在keyPair中
            keyPair = keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }

    /**
     * 对字符串进行BASE64Decoder
     *
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] decryptBASE64(String key) {
        return Base64.getDecoder().decode(key);
    }

    /**
     * 对字节数组进行BASE64Encoder
     *
     * @param key
     * @return
     * @throws Exception
     */
    private static String encryptBASE64(byte[] key) {
        return Base64.getEncoder().encodeToString(key);
    }

    public static void main(String[] args) {
        // 生成的一对key保存好
        try {
            //得到私钥和公钥
            KeyPair keyPair = getRSAKey();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

            String pubKey = encryptBASE64(publicKey.getEncoded());
            String priKey = encryptBASE64(privateKey.getEncoded());
            System.out.println("公钥:" + pubKey);
            System.out.println("私钥:" + priKey);

            // 测试
            String message = "QWERDF";

            System.out.println("明文:" + message);
            String jiami = encryptData(pubKey, message, true);
            System.out.println("公钥加密后:" + jiami);
            String jiemi = decryptData(priKey, jiami, false);
            System.out.println("用私钥解密后的结果是:" + jiemi);

            jiami = encryptData(priKey, message, false);
            System.out.println("私钥加密后:" + jiami);
            jiemi = decryptData(pubKey, jiami, true);
            System.out.println("用公钥解密后的结果是:" + jiemi);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值