首页 > 其他分享 >加解密总结

加解密总结

时间:2023-07-06 17:55:39浏览次数:31  
标签:总结 return String 加解密 static new byte public

1,Base64(编码)

  Base64 编码是我们程序开发中经常使用到的编码方法,它用 64 个可打印字符来表示二进制数据。这 64 个字符是:小写字母 a-z、大写字母 A-Z、数字 0-9、符号"+“、”/“(再加上作为垫字的”=",实际上是 65 个字符),其他所有符号都转换成这个字符集中的字符。Base64 编码通常用作存储、传输一些二进制数据编码方法,所以说它本质上是一种将二进制数据转成文本数据的方案

特征:可以解密,每次结果也是一样的

public class Base64Util {

    /**
     * 加密:利用Java中sun.misc.BASE64Encoder()
     * */
    public static String encrypt(String key){
        return new BASE64Encoder().encode(key.getBytes());
    }

    /**
     * 解密:利用Java中sun.misc.BASE64Encoder()
     * */
    public static String decrypt(String str) throws IOException {
        return new String(new BASE64Decoder().decodeBuffer(str));
    }

    /**
     * 加密:Base64.encode()
     * */
    public static String encrypt1(String key){
        return Base64.encode(key);
    }

    /**
     * 解密:Base64.decode()
     * */
    public static String decrypt1(String key){
        return new String(Base64.decode(key));
    }
}

2,凯撒加密(编码)

简单,经常作为其他加密的一个过程

public class KaisaUtil {
    /***
     * 使用凯撒加密方式加密数据
     * @param orignal 原文
     * @param key 密钥
     * @return 加密后的字符
     */
    public static String encryptKaisa(String orignal, int key) {
        //将字符串转换为数组
        char[] chars = orignal.toCharArray();
        StringBuffer buffer = new StringBuffer();
        //遍历数组
        for(char aChar : chars) {
            //获取字符的ASCII编码
            int asciiCode = aChar;
            //偏移数据
            asciiCode += key;
            //将偏移后的数据转为字符
            char result = (char)asciiCode;
            //拼接数据
            buffer.append(result);
        }
        return buffer.toString();
    }

    /**
     * 使用凯撒加密方式解密数据
     *
     * @param encryptedData :密文
     * @param key           :密钥
     * @return : 源数据
     */
    public static String decryptKaiser(String encryptedData, int key) {
        // 将字符串转为字符数组
        char[] chars = encryptedData.toCharArray();
        StringBuilder sb = new StringBuilder();
        // 遍历数组
        for (char aChar : chars) {
            // 获取字符的ASCII编码
            int asciiCode = aChar;
            // 偏移数据
            asciiCode -= key;
            // 将偏移后的数据转为字符
            char result = (char) asciiCode;
            // 拼接数据
            sb.append(result);
        }

        return sb.toString();
    }
}

3,SHA(摘要加密)

单向,不可逆

public class SHAUtil {
    public static final String KEY_SHA = "SHA";
    public static final String ALGORITHM256 = "SHA-256";
    public static final String ALGORITHM384 = "SHA-384";
    public static final String ALGORITHM512 = "SHA-512";

    public static String encodeSHA(String data) throws NoSuchAlgorithmException {
        byte[] bytes = data.getBytes();
        MessageDigest instance = MessageDigest.getInstance(ALGORITHM512);
        String result = new BASE64Encoder().encode( instance.digest(bytes));
        return result;
    }
}

4,MD5(摘要加密)

MD5 是将任意长度的数据字符串转化成短小的固定长度的值的单向操作,任意两个字符串不应有相同的散列值。因此 MD5 经常用于校验字符串或者文件,因为如果文件的 MD5 不一样,说明文件内容也是不一样的,如果发现下载的文件和给定的 MD5 值不一样,就要慎重使用。

MD5 主要用做数据一致性验证、数字签名和安全访问认证,而不是用作加密。比如说用户在某个网站注册账户时,输入的密码一般经过 MD5 编码,更安全的做法还会加一层盐(salt),这样密码就具有不可逆性。然后把编码后的密码存入数据库,下次登录的时候把密码 MD5 编码,然后和数据库中的作对比,这样就提升了用户账户的安全性。

特征:单向加密,不能解密,每次加密都是一样的

public class Md5Util {

    //盐,可自己定义
    public static final String salt = "yanqi";

    /**
     * Spring 的 DigestUtils
     */
    public static String encrypt(String str){

        //32位,小写
        String md532Lower = DigestUtils.md5DigestAsHex("adcdefg".getBytes());

        return DigestUtils.md5DigestAsHex((salt + md532Lower).getBytes());
    }

    /**
     * JAVA 的 MessageDigest 加密
     * */
    public static String encrypt1(String str) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(str.getBytes());
        return new BigInteger(1, md5.digest()).toString(16);
    }

}

5,DES(对称加密)

对称加密算法就是:加密和解密使用相同密钥的算法

public class DESUtil {

    private static Key key;

    private static String KEY_STR="myYanqi";
    private static String CHARSETNAME="UTF-8";
    private static String ALGORITHM="DES";

    static{
        try {
            //生成DES算法对象
            KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
            //运用SHA1安全策略
            SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
            //设置上密钥种子
            secureRandom.setSeed(KEY_STR.getBytes());
            //初始化基于SHA1的算法对象
            generator.init(secureRandom);
            //生成密钥对象
            key=generator.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //加密
    public static String encrypt(String str){
        //基于BASE64编码,接收byte[]并转换成String
        BASE64Encoder encoder = new BASE64Encoder();
        try {
            //按utf8编码
            byte[] bytes = str.getBytes(CHARSETNAME);
            //获取加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化密码信息
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //加密
            byte[] doFinal = cipher.doFinal(bytes);
            //byte[]to encode好的String 并返回
            return encoder.encode(doFinal);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //解密
    public static String decrypt(String str){
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            //将字符串decode成byte[]
            byte[] bytes = decoder.decodeBuffer(str);
            //获取解密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化解密信息
            cipher.init(Cipher.DECRYPT_MODE, key);
            //解密
            byte[] doFial = cipher.doFinal(bytes);

            return new String(doFial, CHARSETNAME);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

6,AES(对称加密)

AES 与 DES 一样,一共有四种加密模式:

  • 电子密码本模式(ECB)、
  • 加密分组链接模式(CBC)、
  • 加密反馈模式(CFB)
  • 输出反馈模式(OFB)。
public class AESUtil {

    public static final String algorithm = "AES";
    // AES/CBC/NOPaddin
    // AES 默认模式
    // 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
    // IvParameterSpec(key.getBytes());
    // NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
    public static final String transformation = "AES/CBC/PKCS5Padding";
    public static final String key = "1234567812345678";

    /***
     * 加密
     * @param original 需要加密的参数(注意必须是16位)
     * @return
     * @throws Exception
     */
    public static String encryptByAES(String original) throws Exception {

        // 获取Cipher
        Cipher cipher = Cipher.getInstance(transformation);
        // 生成密钥
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
        // 指定模式(加密)和密钥
        // 创建初始化向量
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        // cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        // 加密
        byte[] bytes = cipher.doFinal(original.getBytes());

        return new BASE64Encoder().encode(bytes);
    }

    /**
     * 解密
     * @param encrypted 需要解密的参数
     * @return
     * @throws Exception
     */
    public static String decryptByAES(String encrypted) throws Exception {
        // 获取Cipher
        Cipher cipher = Cipher.getInstance(transformation);
        // 生成密钥
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
        // 指定模式(解密)和密钥
        // 创建初始化向量
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
        // cipher.init(Cipher.DECRYPT_MODE, keySpec);
        // 解密
        byte[] bytes = cipher.doFinal(new BASE64Decoder().decodeBuffer(encrypted));

        return new String(bytes);
    }
}

7,PBE(没用过)

public class PBEUtil {
    public static final String ALGORITHM = "PBEWITHMD5andDES";

    public static final int ITERATION_COUNT = 100;


    public static byte[] initSalt() throws Exception{
        //实例化安全随机数
        SecureRandom random = new SecureRandom();
        return random.generateSeed(8);
    }

    /***
     * 转换密钥
     * @param password 密码
     * @return 密钥
     * @throws Exception
     */
    private static Key toKey(String password) throws Exception{
        //密钥材料
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        //实例化
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        //生成密钥
        return factory.generateSecret(keySpec);
    }

    /***
     * 加密
     * @param data 待加密数据
     * @param password 密钥
     * @param salt
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception{
        //转换密钥
        Key key = toKey(password);
        //实例化PBE参数材料
        PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
        //实例化
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        //初始化
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);
        return cipher.doFinal(data);
    }


    /***
     * 解密
     * @param data 待解密数据
     * @param password 密钥
     * @param salt
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception{
        //转换密钥
        Key key = toKey(password);
        //实例化PBE参数材料
        PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
        //实例化
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        //初始化
        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        //执行操作
        return cipher.doFinal(data);
    }


    public static String showByteArray(byte[] data) {
        if(null == data) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for(byte b : data) {
            sb.append(b).append(",");
        }
        sb.deleteCharAt(sb.length()-1);
        return sb.toString();
    }

}

8,RSA(非对称加密)

公钥加密,提供公钥
私钥解密,自己用的

public class RSAUtil {
    public static final String PUBLIC_KEY = "PUBLIC_KEY";
    public static final String PRIVATE_KEY = "PRIVATE_KEY";

    private static final Base64.Encoder base64Encoder = Base64.getEncoder();
    private static final Base64.Decoder base64Decoder = Base64.getDecoder();

    private static final String ALGORITHM = "RSA";
    /**
     * 签名算法
     */
    private static final String SIGN_TYPE = "SHA1withRSA";
    /**
     * 密钥长度
     */
    private static final Integer KEY_LENGTH = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * 生成秘钥对,公钥和私钥
     *
     * @return 秘钥键值对
     * @throws Exception 创建秘钥对异常
     */
    public static Map<String, Key> genKeyPair() throws Exception {
        Map<String, Key> keyMap = new HashMap<>();
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(KEY_LENGTH); // 秘钥字节数
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    /**
     * 公钥加密
     *
     * @param data      加密前数据
     * @param publicKey 公钥
     * @return 加密后数据
     * @throws Exception 加密异常
     */
    public static byte[] encryptByPublicKey(byte[] data, PublicKey publicKey) throws Exception {
        // 加密数据,分段加密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    public static byte[] encryptByPublicKey(byte[] data, String publicKeyBase64Encoded) throws Exception {
        return encryptByPublicKey(data, parseString2PublicKey(publicKeyBase64Encoded));
    }

    /**
     * 私钥解密
     *
     * @param data       解密前数据
     * @param privateKey 私钥
     * @return 解密后数据
     * @throws Exception 解密异常
     */
    public static byte[] decryptByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
        // 解密数据,分段解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache);
            i++;
            offset = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    public static byte[] decryptByPrivateKey(byte[] data, String privateKeyBase64Encoded) throws Exception {
        return decryptByPrivateKey(data, parseString2PrivateKey(privateKeyBase64Encoded));
    }

    /**
     * 创建签名
     *
     * @param source     要签名的信息
     * @param privateKey 私钥
     * @return 签名
     * @throws Exception 签名异常
     */
    public static byte[] createSign(String source, PrivateKey privateKey) throws Exception {
        Signature signet = Signature.getInstance(SIGN_TYPE);
        signet.initSign(privateKey);
        signet.update(source.getBytes());
        return signet.sign();
    }

    public static byte[] createSign(String source, String privateKeyBase64Encoded) throws Exception {
        return createSign(source, parseString2PrivateKey(privateKeyBase64Encoded));
    }

    /**
     * 校验签名
     *
     * @param expected  期望信息
     * @param sign      签名
     * @param publicKey 公钥
     * @return 结果
     * @throws Exception 校验异常
     */
    public static boolean checkSign(String expected, byte[] sign, PublicKey publicKey) throws Exception {
        Signature signetCheck = Signature.getInstance(SIGN_TYPE);
        signetCheck.initVerify(publicKey);
        signetCheck.update(expected.getBytes());
        return signetCheck.verify(sign);
    }

    public static boolean checkSign(String expected, byte[] sign, String publicKeyBase64Encoded) throws Exception {
        return checkSign(expected, sign, parseString2PublicKey(publicKeyBase64Encoded));
    }

    /**
     * 将base64格式的公钥转换为对象
     *
     * @param publicKeyBase64Encoded base64的公钥
     * @return 公钥
     * @throws Exception 转换异常
     */
    public static PublicKey parseString2PublicKey(String publicKeyBase64Encoded) throws Exception {
        return KeyFactory.getInstance(ALGORITHM).generatePublic(
                new X509EncodedKeySpec(base64Decoder.decode(publicKeyBase64Encoded)));
    }

    /**
     * 将base64格式的私钥转换为对象
     *
     * @param privateKeyBase64Encoded base64的私钥
     * @return 私钥
     * @throws Exception 转换异常
     */
    public static PrivateKey parseString2PrivateKey(String privateKeyBase64Encoded) throws Exception {
        return KeyFactory.getInstance(ALGORITHM).generatePrivate(
                new PKCS8EncodedKeySpec(base64Decoder.decode(privateKeyBase64Encoded)));
    }
}

标签:总结,return,String,加解密,static,new,byte,public
From: https://www.cnblogs.com/cnff/p/17532821.html

相关文章

  • 阿里架构师万字总结:Mybatis插件实现原理,Mybatis就要这么用
     mybatis中的插件,也就是拦截器interceptor,也挺有意思的。它的简单使用,就直接拿文档中的示例来简单说下一、使用使用方式很简单Copy//使用这个注解,表明这是一个拦截器@Intercepts(//方法签名{@Signature(//被拦截方法所在的类type=Executor.class......
  • 第二周第五天进度总结
    2023年7月6日,今天我Java基础学到了P27-两只老虎案例,Javaweb学到了P18-HTML表单标签(四)。今天也是做完了任务,我额外抽出一个半小时教妹妹学会100以内的加减法,只能说还得教,不熟练。读物看到53页了,天梯赛也做了点。在家还是挺无聊的,天气太热,不好出去玩。......
  • <数组中选取子集达到某一目标>问题总结
    这类问题主要分为两种类型:目标值明确,可以把目标值看出背包容量,数组值看做物品,转成背包问题目标值不明确,容量不知道,不能用背包,只能枚举子集的和类型一:类型二:Leetcode1555题目描述给你一个整数数组nums和一个目标值goal。你需要从nums中选出一个子序列,使子序列元素......
  • AI数字人(虚拟人)讨论总结
    AI数字人类型和应用场景?1.二维/三维虚拟人:用于游戏、IP品牌(柳夜熙)、内容创作(http://AI.talk)等。2.真人形象数字人:用于直播卖货,营销/投流广告视频录制(Heygen)、语言学习(CallAnnie)等等。AI数字人的价值是什么?1.代替人说话,提升表达效率和营销效率。比如真人做不到24小时直播,但......
  • Java-基本语法回顾总结[73-84]
    redis与MySQL如何保持数据一致?1.删除redis缓存2.更新MySQL3.删除redis缓存redis的持久化机制两种持久化命令:save:阻塞性持久化,会阻塞redis主进程,直到持久化完成bgsave:非阻塞性持久化,通过新建子线程专门持久化,从而不影响redis主进程手动就是上面两种命令自动就是sa......
  • nvm安装node.js总结
    nvm安装node.js总结什么是nvm?nvm(Node.jsversionmanager)是一个命令行应用,可以协助您快速地更新、安装、使用、卸载本机的全局node.js版本。为什么要用nvm?有时候,我们可能同时在进行多个项目开发,而多个项目所使用的node版本又是不一样的,或者是要用最新的node版本进行......
  • 差分学习笔记与总结
    差分学习笔记与总结目录差分一维差分What背景\(b_1\)的值\(b_2\)的值\(b_3\)的值\(b_i\)的值怎么用作用1作用2模板例题link题目大意CODE二维差分What作用模板模板题题目大意CODE差分前置知识-前缀和一维差分What差分可理解为前缀和的逆运算前缀和背景现有数......
  • go select 使用总结
    转载请注明出处:在Go语言中,select语句用于处理多个通道的并发操作。它类似于switch语句,但是select语句用于通信操作,而不是条件判断。select语句会同时监听多个通道的操作,并选择其中一个可用的通道进行操作。select语句的语法如下:select{case<-channel1://......
  • 崇明区一模卷错题总结
    1.advisetodo2.forgetful健忘的3.被动语态不会被动语态:1,一般现在时:am,is,are+动词过去分词例如:Theballisplayed,everyday这个球每天被踢2,一般过去时:was,were+动词过去分词Theballwasplayed,yesterday这个球昨天被踢3,一般将来时:willbe+动词过去分......
  • 7.5总结
    今天早上依旧和往常一样醒的比较晚就没吃早饭,早上起来自己泡了个方便面吃,吃完泡面就不早了就,打了会游戏就中午了,中午吃完饭后发现有点困,就简单的睡了个午觉,醒了之后就学习了会java,主要是看的学习视频,没啥大问题,学了一会就去练车了,我真的吐了,热的要死啊,练车练完之后就不早了,就回家......