• AES加解密


    密钥是AES算法实现加密和解密的根本。对称加密算法之所以对称,是因为这类算法对明文的加密和解密需要使用同一个密钥。

    AES支持三种长度的密钥: 128位,192位,256位

    平时大家所说的AES128AES192AES256,实际上就是指AES算法对不同长度密钥的使用。

    三种密钥的区别:

    从安全性来看,AES256安全性最高。从性能看,AES128性能最高。本质原因是它们的加密处理轮数不同。

    AES原理:AES是对数据按128位,也就是16个字节进行分组进行加密的,每次对一组数据加密需要运行多轮,而输入密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节,如果用户输入的密钥长度不是这几种长度,也会补成这几种长度。

      无论输入密钥是多少字节,加密还是以16字节的数据一组来进行的,密钥长度的不同仅仅影响加密运行的轮数。

    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Base64;
    
    
    public class TestController {
        public static void main(String[] args) {
            try {
                //根据指定字符串生成秘钥
                KeyGenerator kg = KeyGenerator.getInstance("AES");
                kg.init(128,new SecureRandom("ceshi".getBytes()));
                SecretKey sk = kg.generateKey();
                String keyStr = Base64.getEncoder().encodeToString(sk.getEncoded());
    
                byte[] iv = Base64.getDecoder().decode(keyStr);
                byte[] key = Base64.getDecoder().decode(keyStr);
                String content = "测试";
    
                String encrypted = Base64.getEncoder().encodeToString(encrypt(iv, key, content.getBytes()));
                System.out.println("加密后: " + encrypted);
    
                String raw = new String(decrypt(iv, key, Base64.getDecoder().decode(encrypted)));
                System.out.println("解密后: " + raw);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
    
        public static byte[] encrypt(byte[] iv, byte[] key, byte[] raw) {
    
            try {
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
                IvParameterSpec ips = new IvParameterSpec(iv);
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ips);
                return cipher.doFinal(raw);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static byte[] decrypt(byte[] iv, byte[] key, byte[] encryptContent) {
    
            try {
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                IvParameterSpec ips = new IvParameterSpec(iv);
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, ips);
                return cipher.doFinal(encryptContent);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    }

    填充模式:

    PKCS1Padding:PKCS#1(v1.5)中规定当RSA的密钥长度是1024b,如果使用PKCS1Padding填充,则原文数据最多117B。如果原文不满足长度要求,则在加密前需要进行填充。

    PKCS5Padding:PKCS#5填充是将数据填充到8的倍数,填充后数据长度的计算公式是 定于元数据长度为x, 填充后的长度是 x + (8 - (x % 8)), 填充的数据是 8 - (x % 8),块大小固定为8字节

    PKCS7Padding:假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小;PKCS5只填充到8字节,而PKCS7可以在1-255之间任意填充。

    ZeroPadding:数据长度不对齐时使用0填充,否则不填充。

    NoPadding:待补充

    参考连接:https://blog.csdn.net/qq_36838191/article/details/80494043

  • 相关阅读:
    Trusted_Connection
    自定义绑定表达式
    【Android】Uri、UriMatcher、ContentUris详解
    Android事件传递机制【按键事件】
    ANDROID 9.PNG 图片制作
    Android ProGuard实例教程
    Android 几个Info系列类的总结
    NDK的讲义
    Android FrameWork——Touch事件派发过程详解
    【Android面试】Android面试题集锦 (陆续更新)
  • 原文地址:https://www.cnblogs.com/lijianda/p/16172695.html
Copyright © 2020-2023  润新知