精华内容
下载资源
问答
  • 对称算法的加密模式
    千次阅读 多人点赞
    2022-07-21 19:20:35

      随着网络时代的兴起,在互联网上的传输的数据也越来越多,越来越重要,为了避免数据被截获过,加密算法应运而生,今天我们就利用Java平台,给大家讲讲常见的几种加密算法。

    1,哈希算法

      (1) 哈希算法又称(摘要算法)

    哈希算法的作用是:对任意一组数据进行计算,得到一个固定长度的输出摘要。

    哈希算法的目的是:为了验证数据是否被篡改。

    哈希算法的特点是:相同的输入一定得到相同的输出,不同的输入大概率得到不同的输出。

    (2)常见的几种哈希算法

    算法输出长度(位)输出字节(字节)
    MD5128 bits16 bytes
    SHA-1160 bits

    20 bytes

    RipMD-160160 bits20 bytes
    SHA-256256 bits32 bytes
    SHA-512512 bits64 bytes

    (3) 如何利用哈希算法进行数据加密

       下面我们以加密一个字符串(Hello world)为例,利用hash算法中的MD5为例。

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class AAA {
    	public static void main(String[] args) {
    		String str = "Hello world";
    		//利用try-catch块处理可能出现的异常
    		try {
    			//根据当前算法,获取加密工具对象(摘要)
    			MessageDigest md5 = MessageDigest.getInstance("MD5");
    			
    			//更新原始数据,把字符串类型转化成字节
    			md5.update(str.getBytes());
    			byte[] resultByteArray = md5.digest();
    			
    			//加密后的字节数组需要转化成字符串,提前准备一个Stringbuilder
    			StringBuilder result = new StringBuilder(); 
    			
    			for(byte bite : resultByteArray) {
    
    				//利用String.format方法设置加密后的字符串格式
    				result.append(String.format("%02x", bite));
    
    			}
    
    			//打印输出加密后的字符串
    			System.out.println(result);
    
    		} catch (NoSuchAlgorithmException e) {
    			e.printStackTrace();
    		}
    	}
    
    }

    2,对称式加密算法

    (1)  对称式加密算法就是传统的用一个密码用于加密和解密。从程序的角度来看:

    加密:一个函数,它接收密码和明文  secert = encrpy(key ,message);

    解密:一个函数,它接收密码和密文,plain = decrpy(key , secert);

    (2)在软件开发的过程中,常见的对称加密算法有:

    算法密钥长度工作模式填充模式
    DES56/64ECB/CBC/PCBC/CTR....noPadding/PKCS5Pading/....
    AES128/192/256ECB/CBC/PCBC/CTR.....noPadding/PKCS5Pading/....
    IDEA128ECBPKCS5Pading/PKS7Paddong/...

    (3)AES加密:AES算法是目前应用最广泛的加密算法。比较常见的工作模式是ECB和CBC

    我们假设密码明文是(Hello.world),用ECB和CBC两种模式来模拟加密及解密。

    ECB:

    import java.security.*;
    import java.util.Base64;
    
    import javax.crypto.*;
    import javax.crypto.spec.*;
    
    public class Main {
        public static void main(String[] args) throws Exception {
    
            // 原文:
            String message = "Hello, world!";
            System.out.println("Message(原始信息): " + message);
            
            // 128位密钥 = 16 bytes Key:
            byte[] key = "1234567890abcdef".getBytes();
            
            // 加密:
            byte[] data = message.getBytes();
            byte[] encrypted = encrypt(key, data);
            System.out.println("Encrypted(加密内容): " + 
            					Base64.getEncoder().encodeToString(encrypted));
            
            // 解密:
            byte[] decrypted = decrypt(key, encrypted);
            System.out.println("Decrypted(解密内容): " + new String(decrypted));
        }
    
        // 加密:
        public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        	// 创建密码对象,需要传入算法/工作模式/填充模式
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        	
            // 根据key的字节内容,"恢复"秘钥对象
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            
            // 初始化秘钥:设置加密模式ENCRYPT_MODE
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            
            // 根据原始内容(字节),进行加密
            return cipher.doFinal(input);
        }
    
        // 解密:
        public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        	// 创建密码对象,需要传入算法/工作模式/填充模式
        	Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            
        	// 根据key的字节内容,"恢复"秘钥对象
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            
            // 初始化秘钥:设置解密模式DECRYPT_MODE
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            
            // 根据原始内容(字节),进行解密
            return cipher.doFinal(input);
        }
    }

    CBC:

    package com.apesource.demo04;
    
    import java.security.*;
    import java.util.Base64;
    
    import javax.crypto.*;
    import javax.crypto.spec.*;
    
    public class Main {
    	public static void main(String[] args) throws Exception {
            // 原文:
            String message = "Hello, world!";
            System.out.println("Message(原始信息): " + message);
            
            // 256位密钥 = 32 bytes Key:
            byte[] key = "1234567890abcdef1234567890abcdef".getBytes();
            
            // 加密:
            byte[] data = message.getBytes();
            byte[] encrypted = encrypt(key, data);
            System.out.println("Encrypted(加密内容): " + 
    				Base64.getEncoder().encodeToString(encrypted));
            
            // 解密:
            byte[] decrypted = decrypt(key, encrypted);
            System.out.println("Decrypted(解密内容): " + new String(decrypted));
        }
    
        // 加密:
        public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            // 设置算法/工作模式CBC/填充
        	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        	
        	// 恢复秘钥对象
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            
            // CBC模式需要生成一个16 bytes的initialization vector:
            SecureRandom sr = SecureRandom.getInstanceStrong();
            byte[] iv = sr.generateSeed(16); // 生成16个字节的随机数
            System.out.println(Arrays.toString(iv));
            IvParameterSpec ivps = new IvParameterSpec(iv); // 随机数封装成IvParameterSpec参数对象
            
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);
            
            // 加密
            byte[] data = cipher.doFinal(input);
            
            // IV不需要保密,把IV和密文一起返回:
            return join(iv, data);
        }
    
        // 解密:
        public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            // 把input分割成IV和密文:
            byte[] iv = new byte[16];
            byte[] data = new byte[input.length - 16];
            
            System.arraycopy(input, 0, iv, 0, 16); // IV
            System.arraycopy(input, 16, data, 0, data.length); //密文
            System.out.println(Arrays.toString(iv));
            
            // 解密:
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 密码对象
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); // 恢复秘钥
            IvParameterSpec ivps = new IvParameterSpec(iv); // 恢复IV
            
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);
            
            // 解密操作
            return cipher.doFinal(data);
        }
        
        // 合并数组
        public static byte[] join(byte[] bs1, byte[] bs2) {
            byte[] r = new byte[bs1.length + bs2.length];
            System.arraycopy(bs1, 0, r, 0, bs1.length);
            System.arraycopy(bs2, 0, r, bs1.length, bs2.length);
            return r;
        }
    }
    
    

    3,非对称式加密算法

      (1)非对称式加密:

                加密和解密使用的不是相同的密钥,只有同一个公钥-私钥才能正常加密和解密。

    (2)非对称式加密的缺点:

                 运算速度特别慢,比对称加密运行速度慢得多。

    (3)在实际应用中,非对称式加密和对称加密一起使用。流程如下:

                A生成一个随机的AES口令,然后用小红的公钥通过RSA加密这个口令,发给B。

               B用自己的RSA私钥解密得到AES口令。

               A与B使用这个共享的AES口令用AES加密通信。

    (4)下面我们用JAVA编写一下RSA加密算法:

    import java.math.BigInteger;
    import java.security.GeneralSecurityException;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import javax.crypto.Cipher;
    
    // RSA
    public class Main {
    	public static void main(String[] args) throws Exception {
    		// 明文:
    		byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");
    
    		// 创建公钥/私钥对:
    		Human alice = new Human("Alice");
    
    		// 用Alice的公钥加密:
    		// 获取Alice的公钥,并输出
    		byte[] pk = alice.getPublicKey();
    		System.out.println(String.format("public key(公钥): %x", new BigInteger(1, pk)));
    
    		// 使用公钥加密
    		byte[] encrypted = alice.encrypt(plain);
    		System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));
    
    		// 用Alice的私钥解密:
    		// 获取Alice的私钥,并输出
    		byte[] sk = alice.getPrivateKey();
    		System.out.println(String.format("private key(私钥): %x", new BigInteger(1, sk)));
    
    		// 使用私钥解密
    		byte[] decrypted = alice.decrypt(encrypted);
    		System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
    	}
    }
    
    // 用户类
    class Human {
    	// 姓名
    	String name;
    
    	// 私钥:
    	PrivateKey sk;
    
    	// 公钥:
    	PublicKey pk;
    
    	// 构造方法
    	public Human(String name) throws GeneralSecurityException {
    		// 初始化姓名
    		this.name = name;
    
    		// 生成公钥/私钥对:
    		KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
    		kpGen.initialize(1024);
    		KeyPair kp = kpGen.generateKeyPair();
    
    		this.sk = kp.getPrivate();
    		this.pk = kp.getPublic();
    	}
    
    	// 把私钥导出为字节
    	public byte[] getPrivateKey() {
    		return this.sk.getEncoded();
    	}
    
    	// 把公钥导出为字节
    	public byte[] getPublicKey() {
    		return this.pk.getEncoded();
    	}
    
    	// 用公钥加密:
    	public byte[] encrypt(byte[] message) throws GeneralSecurityException {
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.ENCRYPT_MODE, this.pk); // 使用公钥进行初始化
    		return cipher.doFinal(message);
    	}
    
    	// 用私钥解密:
    	public byte[] decrypt(byte[] input) throws GeneralSecurityException {
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.DECRYPT_MODE, this.sk); // 使用私钥进行初始化
    		return cipher.doFinal(input);
    	}
    }

         

    更多相关内容
  • 在PHP的语法环境里,有urlencode与urldecode,base64_encode和base64_decode自带的对称算法,不过这些自带的算法不能称之为加密算法,只能说是编码方式而已。可是我们可以利用这些来进行一些加工,来实现简单的加密和...
  • 在openssl或其他密码相关的资料中,我们经常看到对称加密算法有ECB、CBC之类加密模式的简称,到底这些加密模式是什么呢?它们之间有什么不同呢,今天就是为大家解开这个迷。 在现有的对称加密算法中,主要有4种加密...

    在openssl或其他密码相关的资料中,我们经常看到对称加密算法有ECB、CBC之类加密模式的简称,到底这些加密模式是什么呢?它们之间有什么不同呢,今天就是为大家解开这个迷。
    在现有的对称加密算法中,主要有4种加密处理模式,这4种加密处理模式一般是针对块加密算法而言的,如DES算法。这4种加密模式罗列如下: 模式中文描述 英文名称(Openssl缩写)
    电子密码本模式 Electronic Code Book(ECB)
    加密块链模式 Cipher Block Chaining(CBC)
    加密反馈模式 Cipher Feedback Mode(CFB)
    输出反馈模式 Output Feedback Mode(OFB)

    下面我们分别介绍这4种加密模式。
    【电子密码本模式】(ECB)
    这种模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。比如DES算法,一个64位的密钥,如果采用该模式加密,就是将要加密的数据分成每组64位的数据,如果最后一组不够64位,那么就补齐为64位,然后每组数据都采用DES算法的64位密钥进行加密。下图:


    My name |is Drago|nKing

    上图“My name is DragonKing”这句话每8个字符(64位)作为一块,然后使用一个相同的64位的密钥对每个块进行加密,最后一块不足64位,就补齐后再进行加密。
    可以看到,因为ECB方式每64位使用的密钥都是相同的,所以非常容易获得密文进行密码破解,此外,因为每64位是相互独立的,有时候甚至不用破解密码,只要简单的将其中一块替换就可以达到黑客目的。
    【加密块链模式】(CBC)
    该模式如下图所示:
    在这里插入图片描述
    从这两个图中大家可以看到,CBC模式的加密首先也是将明文分成固定长度(64位)的块(P0,P1…),然后将前面一个加密块输出的密文与下一个要加密的明文块进行XOR(异或)操作计算,将计算结果再用密钥进行加密得到密文。第一明文块加密的时候,因为前面没有加密的密文,所以需要一个初始化向量(IV)。跟ECB方式不一样,通过连接关系,使得密文跟明文不再是一一对应的关系,破解起来更困难,而且克服了只要简单调换密文块可能达到目的的攻击。
    但是该加密模式的缺点是不能实时解密,也就是说,必须等到每8个字节都接受到之后才能开始加密,否则就不能得到正确的结果。这在要求实时性比较高的时候就显得不合适了。所以才有了下面两种加密模式。
    【加密反馈模式】(CFB)
    加密反馈模式为了克服必须等待8个字节全部得到才能进行解密的缺点,采用了一个64位(8个字节)的位移寄存器来获得密文,如下图所示:
    在这里插入图片描述
    上面两个图中C2、C3以及P10等都是一个字节(8位)的数据,所以能够实现字符的实时加密和解密,不用再等到8个字节都接受到之后再进行解密。图示是在进行第10个字节数据的加密和解密过程,在该过程中,先从移位寄存器取8个字节的数据(C2到C9)用密钥进行加密,然后取加密数据最左边的一个字节跟输入的明文P10进行XOR(异或)操作,得到的值作为输出密文C10,同时将C10送入到移位寄存器中。
    需要注意的是,如果其中有一个字节的密文在传输的时候发生错误(即使是其中的一位),那么它出现在移位寄存器期间解密的8个字节的数据都会得不到正确的解密结果,当然,这8个字节过去之后,依然可以得到正确的解密结果。但是一个比特错误就影响到8个字节(64个比特)的正确结果,导致鲁棒性太差,所以就又提出了下面的加密模式OFB。
    【输出反馈模式】(OFB)
    输出反馈模式OFB跟CFB几乎是一样的,除了其以为寄存器的输入数据稍微有一点不同之外,如下图:
    在这里插入图片描述
    可以看到,这种方法因为没有采用密文作为加密的数据,所以克服了由于传输过程中由于单个比特导致64个相关比特解密失败的情况,在本模式下,如果一个比特发生错误了,那么只会影响其本身对应的一个比特,而不会影响别的。但是相对于其它模式,因为数据之间相关性小,这种加密模式是比较不安全的,所以在应用的时候除非特别需要,一般不提倡应用OFB模式。

    展开全文
  • 对称加密算法

    2022-06-15 19:05:40
    对称加密算法的原理

    对称加密

    一 对称加密原理

    对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。自1977年美国颁布DES(Data Encryption Standard)密码算法作为美国数据加密标准以来,对称密码体制迅速发展,得到了世界各国的关注和普遍应用。对称密码体制从工作方式上可以分为分组加密和序列密码两大类。

    二 对称加密体制

    对称密码体制分两种:

    (1)流密码

    对明文的单个位(或字节)进行运算,明文加密后密文基本保
    和明文同样长度。常用流密码算法有RC4、SEAL等。同步流密码:发送方和接收方在传递信息时同步进行加解密操作,密文内容如果在传输过程中被篡改删除或者插入,会导致同步失效,解密失败。必须重新同步来实现解密,恢复密文。如果传输过程中一个加密位改变,则只影响该位的恢复,对后续密文不影响。但是,主动攻击者可以选择性的对密文字符进行改动,并准确知道这些改动对明文的影响。因此,同步流密码具有同步性,无错误传递性、主动性三种特性。适用于为音频或视频供版权保护。自同步流密码:与同步流密码相比,是一种有记忆变换的密码。每一个密钥与已产生的固定数量的密文位有关,密钥由已生成的密文决定。在密文传输过程中如果一个密文位发生改变,该位的变化会影响到后续有限位(如 n 位)的密文正确解密。

    (2)分组密码

    将明文信息划分成不同的组(或块),分别对每个组(或块)进行运算。多用于网络加密。分组长度越长,密码分析越困难,越不利于操作和运算,分组长度应权衡安全性与实用性。常用的有 DES 、 AES 等

    三 对称加密组成部分

    (1) 明文(plaintext):原始消息,作为算法的输入;
    (2) 加密算法(encryption algorithm):对明文进行各种替换和转换;
    (3)密钥(secret key):密钥也是加密算法的输入之一,算法进行的具体替换和转换取决于密钥;
    (4)密文(ciphertext):已被加密算法打乱的消息输出;
    (5)解密算法(decryption algorithm):本质是加密算法的反向执行,使用密文和同一个密钥作为输入产生原始明文。

    四 对称加密的四种模式

    1 ECB

    每次加密产生独立密文分组,每组加密结果不对别组产生影响,相同明文加密产生相同密文,无初始化向量。

    优点:简单易行,没有误差传递的问题

    缺点:不能隐藏明文的模式,明文重复密文也会重复,对明文进行主动攻击的可能
    性较高。

    用途:适合加密密钥、随机数等短数据,例如安全传递 DES 密钥, ECB 是最适合的模式。

    2 CBC

    明⽂加密前先与前⾯的密⽂进⾏异或后再加密,因此只要选择不同的初始向量,就会产⽣不同的密⽂。

    优点:加密后的密⽂上下⽂关联,即使明⽂相同密⽂也不同;密⽂内容如果被替换、删除或在⽹络传输中发⽣错误,后 续密⽂即被破坏,⽆法解密还原。

    缺点:不利于计算,误差传递,如果在加密的过程中发⽣错误,错误将会被⽆限放⼤,导致加密失败,需要初始化向量

    用途:可加密任意长度的数据,适用于计算产生监测数据完整性的消息的认证码mac

    3 CFB

    类似于⾃同步流密码,分组加密后将密⽂和明⽂进⾏移位异或狗得到输出。

    优点:隐藏了明⽂的模式,分组密码转换为流模式,可产⽣密钥流,可及时加密传送⼩于分组的数据。

    缺点:与CBC相似,不利于并⾏计算,误差传送,需要初始化向量。

    ⽤途:引错误传播⽆界,可⽤于检查发现明⽂密⽂的篡改

    4 OFB

    将分组密码作为同步流密码运⾏,没有错误扩散的问题。与明⽂分组进⾏异或的输⼊部分是反复加密后得到的

    优点:隐藏明⽂模式;分组密码转换为流模式;⽆误差传送问题;可及时加密传送⼩于分组的数据。

    缺点:不利于进⾏计算,对明⽂的主动攻击是可能的;安全性低于CFB.

    ⽤途:适⽤于加密冗余性较⼤的数据,⽐如语⾳,图像数据;

    五 DES Tool 工具的使用

    在这里插入图片描述
    如上图所示,对于输入在途图中“明文”:文本框中的字符串,在“密钥1”文本框中输入一串密钥,然后点击加密按钮,DesTool会在右面“密文”文本框中显示采用Des加密算法加密后的密文。

    在这里插入图片描述
    如上图所示,在解密过程中,必须使用和加密时,同一把密钥否则会出现乱码,无法解密。,

    展开全文
  • RSA非对称加密算法

    2019-02-14 23:12:03
    主要介绍RSA非对称加密算法的由来和应用场景,以及加密原理
  • 微信搜索:码农StayUp ... 上篇介绍了《单向散列加密...单向散列加密只能够对消息进行加密(严格来说是计算消息的摘要),想要实现对密文解密,需要使用其它加密方式了。今天介绍一个在信息安全领域中,比较重要的加密方..

    微信搜索:码农StayUp
    主页地址:https://gozhuyinglong.github.io
    源码分享:https://github.com/gozhuyinglong/blog-demos

    上篇介绍了《单向散列加密》,它是一种消息摘要算法。该算法在信息安全领域,有很多重要的应用场景,比如:用户密码保护、数字签名、文件完整性校验、云盘妙传等。

    单向散列加密只能够对消息进行加密(严格来说是计算消息的摘要),想要实现对密文解密,需要使用其它加密方式了。今天介绍一个在信息安全领域中,比较重要的加密方式——对称加密。

    下面是本篇讲述内容:
    目录

    加密、解密和密钥

    加密(Encrypt)是从明文生成密文的步骤,解密(Decrypt)是从密文还原成明文的步骤,而这两个步骤都需要用到密钥(Key)。这和我们现实中,用钥匙上锁和开锁是一样的。

    加密、解密和密钥

    什么是对称加密

    对称加密(Symmetric Cryptography)是密码学中的一类加密算法,这类算法在加密和解密时,使用相同的密钥。

    对称加密又称为共享密钥加密,其最大的缺点是,对称加密的安全性依赖于密钥,一旦泄露,就意味着任何人都能解密消息。

    对称加密的优点是加密速度快,所以在很多场合被使用。

    常见算法

    本节介绍对称加密的一些常见算法,包括DES、3DES和AES。

    DES算法

    DES(Data Encryption Standard,中文:数据加密标准),是一种对称加密算法。该算法在1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并于1977年被发布,随后在国际上广泛流传开来。然而,随着计算机的进步,DES 已经能够被暴力破解,所以该算法已经不安全了。

    DES是一种分组密码(Block Cipher,或者叫块加密),即将明文按64比特进行分组加密,每组生成64位比特的密文。它的密钥长度为56比特(从规格上来说,密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实际长度为56比特)。

    DES算法

    3DES算法

    三重数据加密算法(Triple Data Encryption Algorithm,缩写为TDEA),简称3DES(Triple-DES),是DES的增强版,相当于对每组数据应用了三次DES算法。

    由于DES算法的密钥长度过短,容易被暴力破解,为了解决这一问题,设计出了该算法。它使用简单的方法,通过增加DES密钥长度的方式来避免类似攻击,而不是一种全新的密码算法。

    该算法在每次应用DES时,使用不同的密钥,所以有三把独立密钥。这三把密钥组成一起,是一个长度为168(56 + 56 + 56)比特的密钥,所以3DES算法的密钥总长度为168比特。

    3DES的加密过程,并不是进行三次DES加密(加密→加密→加密),而是以密钥1、密钥2、密钥3的顺序,进行加密解密加密的过程。

    3DES加密

    3DES的解密过程和加密正好相反,是以密钥3、密钥2、密钥1的顺序,进行解密加密解密的操作。

    3DES解密

    AES算法

    AES(Advanced Encryption Standard),即高级加密标准,是取代DES算法的一种新的对称加密算法。AES算法是从全世界的企业和密码学家,提交的对称密码算法中竞选出来的,最终 Rijndael 加密算法胜出,所以AES又称为 Rijndael 加密算法。

    AES也是一种分组密码,它的分组长度为128比特,密钥长度可以为128比特、192比特或256比特。

    AES算法

    分组密码的模式

    上面介绍的DES、3DES和AES都属于分组密码,它们只能加密固定长度的明文。如果需要加密更长的明文,就需要对分组密码进行迭代,而分组密码的迭代方法称为分组密码的模式(Model)。简而一句话:分组密码的模式,就是分组密码的迭代方式。

    分组密码有很多种模式,这里主要介绍以下几种:ECB、CBC、CFB、OFB、CTR。

    明文分组与密文分组

    在下面对模式的介绍时,会用到两个术语,这里先介绍一下:

    在分组密码中,我们称每组的明文为明文分组,每组生成的密文称为密文分组

    若将所有的明文分组合并起来就是完整的明文(先忽略填充),将所以的密文分组合并起来就是完整的密文。

    ECB模式

    ECB(Electronic CodeBook)模式,即电子密码本模式。该模式是将明文分组,加密后直接成为密文分组,分组之间没有关系。

    ECB模式

    ECB模式是所有模式中最简单的一种,该模式的明文分组与密文分组是一一对应的关系,若明文分组相同,其密文分组也一定相同。因此,ECB模式也是最不安全的模式。

    CBC模式

    CBC(Cipher Block Chaining)模式,即密码分组链接模式。该模式首先将明文分组与前一个密文分组进行XOR运算,然后再进行加密。只有第一个明文分组特殊,需要提前为其生成一个与分组长度相同的比特序列,进行XOR运算,这个比特序列称为初始化向量(Initialization Vector),简称IV

    CBC模式

    CFB模式

    CFB(Cipher FeedBack)模式,即密文反馈模式。该模式首先将前一个密文分组进行加密,再与当前明文分组进行XOR运算,来生成密文分组。同样CFB模式也需要一个IV。

    CFB模式

    OFB模式

    OFB(Output FeedBack)模式,即输出反馈模式。该模式会产生一个密钥流,即将密码算法的前一个输出值,做为当前密码算法的输入值。该输入值再与明文分组进行XOR运行,计算得出密文分组。该模式需要一个IV,进行加密后做为第一个分组的输入。

    OFB模式

    CTR模式

    CTR(CounTeR)模式,即计数器模式。该模式也会产生一个密钥流,它通过递增一个计数器来产生连续的密钥流。对该计数器进行加密,再与明文分组进行XOR运算,计算得出密文分组。

    CTR模式

    分组密码的填充

    在分组密码中,当数据长度不符合分组长度时,需要按一定的方式,将尾部明文分组进行填充,这种将尾部分组数据填满的方法称为填充(Padding)。

    No Padding

    即不填充,要求明文的长度,必须是加密算法分组长度的整数倍。

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD DD DD DD DD |
    

    ANSI X9.23

    在填充字节序列中,最后一个字节填充为需要填充的字节长度,其余字节填充0

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 04 |
    

    ISO 10126

    在填充字节序列中,最后一个字节填充为需要填充的字节长度,其余字节填充随机数

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD 81 A6 23 04 |
    

    PKCS#5和PKCS#7

    在填充字节序列中,每个字节填充为需要填充的字节长度

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |
    

    ISO/IEC 7816-4

    在填充字节序列中,第一个字节填充固定值80,其余字节填充0。若只需填充一个字节,则直接填充80

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD 80 00 00 00 |
    
    ... | DD DD DD DD DD DD DD DD | DD DD DD DD DD DD DD 80 |
    

    Zero Padding

    在填充字节序列中,每个字节填充为0

    ... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |
    

    Java代码实现

    Java在底层已经封装好了对称加密的实现, 我们只需要使用即可。现在介绍几个重要的类:

    SecureRandom类

    SecureRandom类是一个强安全的随机数生成器(Random Number Generator,简称:RNG),加密相关的推荐使用此随机数生成器。

    我们可以通过构造方法生成一个实例,或者向构造方法传递一个种子来创建实例。

    SecureRandom random = new SecureRandom();
    

    KeyGenerator类

    KeyGenerator类是对称密码的密钥生成器,需要指定加密算法,来生成相应的密钥。

    Java中支持的算法:

    • AES (128)
    • DES (56)
    • DESede (168)
    • HmacSHA1
    • HmacSHA256

    下面是一些标准算法的介绍:

    标准算法

    生成密钥代码如下:

    /**
     * 通过密码和算法获取 Key 对象
     *
     * @param key       密钥
     * @param algorithm 算法,例如:AES (128)、DES (56)、DESede (168)、HmacSHA1、HmacSHA256
     * @return 密钥 Key
     * @throws Exception
     */
    private static Key getKey(byte[] key, String algorithm) throws Exception {
        // 通过算法获取 KeyGenerator 对象
        KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
        // 使用密钥做为随机数,初始化 KeyGenerator 对象
        keyGenerator.init(new SecureRandom(key));
        // 生成 Key
        return keyGenerator.generateKey();
    }
    

    Cipher类

    Cipher类提供了加密和解密的功能。该类需要指定一个转换(Transformation)来创建一个实例,转换的命名方式:算法名称/工作模式/填充方式

    下面是Java支持的转换:

    • AES/CBC/NoPadding (128)
    • AES/CBC/PKCS5Padding (128)
    • AES/ECB/NoPadding (128)
    • AES/ECB/PKCS5Padding (128)
    • DES/CBC/NoPadding (56)
    • DES/CBC/PKCS5Padding (56)
    • DES/ECB/NoPadding (56)
    • DES/ECB/PKCS5Padding (56)
    • DESede/CBC/NoPadding (168)
    • DESede/CBC/PKCS5Padding (168)
    • DESede/ECB/NoPadding (168)
    • DESede/ECB/PKCS5Padding (168)
    • RSA/ECB/PKCS1Padding (1024, 2048)
    • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
    • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

    下面是一些标准的模式:

    标准模式

    下面是一些标准的填充:

    标准填充

    加密代码如下:

    private static final String DES_ALGORITHM = "DES";
    private static final String DES_TRANSFORMATION = "DES/ECB/PKCS5Padding";
    
    /**
     * DES 加密
     *
     * @param data 原始数据
     * @param key  密钥
     * @return 密文
     */
    private static byte[] encryptDES(byte[] data, byte[] key) throws Exception {
        // 获取 DES Key
        Key secretKey = getKey(key, DES_ALGORITHM);
    
        // 通过标准转换获取 Cipher 对象, 由该对象完成实际的加密操作
        Cipher cipher = Cipher.getInstance(DES_TRANSFORMATION);
        // 通过加密模式、密钥,初始化 Cipher 对象
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 生成密文
        return cipher.doFinal(data);
    }
    

    解密代码如下:

    private static final String DES_ALGORITHM = "DES";
    private static final String DES_TRANSFORMATION = "DES/ECB/PKCS5Padding";
    
    /**
     * DES 解密
     *
     * @param data 密文
     * @param key  密钥
     * @return 原始数据
     */
    private static byte[] decryptDES(byte[] data, byte[] key) throws Exception {
        // 获取 DES Key
        Key secretKey = getKey(key, DES_ALGORITHM);
        // 通过标准转换获取 Cipher 对象, 由该对象完成实际的加密操作
        Cipher cipher = Cipher.getInstance(DES_TRANSFORMATION);
        // 通过解密模式、密钥,初始化 Cipher 对象
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // 生成原始数据
        return cipher.doFinal(data);
    }
    

    完整代码

    完整代码请访问我的Github,若对你有帮助,欢迎给个⭐,感谢~~🌹🌹🌹

    https://github.com/gozhuyinglong/blog-demos/blob/main/java-source-analysis/src/main/java/io/github/gozhuyinglong/utils/SymmetricKeyUtil.java

    推荐阅读

    扫码关注,不迷路

    展开全文
  • 对称算法分类及加密模式

    千次阅读 2017-03-09 22:15:48
    对称算法分类流加密(stream cipher)加密和解密双方使用相同伪随机加密数据流(即密钥),一般都是逐位异或或者随机置换数据内容,常见的流加密算法如RC4。 流加密中,密钥的长度和明文的长度是一致的。假设明文的...
  • C语言实现AES-128对称加解密算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86529111 分析代码
  • 对称加密算法和非对称加密算法

    千次阅读 2020-10-15 17:47:18
    然后传给服务器 服务器收到信息后,用私钥解密,提取出对称加密算法对称密钥后,服务器说:(好的)对称密钥加密 后续两者之间信息的传输就可以使用对称加密方式了 这是个非常非常经典的数据传输过程,也是Https...
  • 本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下: python3.6此库安装方式,需要pip3 install pycryptodome。 如有site-packages中存在crypto、pycrypto,在pip之前,需要pip3 ...
  • 主要介绍了Java 对称加密使用DES / 3DES / AES 这三种算法分别实现的相关资料,这里提供了实例代码,需要的朋友可以参考下
  • 在1976年,Witfield Dime和Martin E·HeBman描述了发展一种立足于两个不同的密钥的加密算法的可能性[Diffie 16]。这些密钥中的一个是公开的,另一个是秘密的或“私有的”。这将有可能使某个人用公开密钥去加密一...
  • C语言实现国密SM4对称加解密算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86578753 分析代码
  • 利用MFC实现AES非对称加密算法,其中有详细的算法注释 利用MFC实现AES非对称加密算法,其中有详细的算法注释
  • 本文实例讲述了C#实现简单的RSA非对称加密算法。分享给大家供大家参考,具体如下: 界面控件 namespace RSA算法 { partial class Form1 { /// /// 必需的设计器变量。 /// private System.ComponentModel....
  • 对称加密算法

    千次阅读 2022-04-28 17:53:16
    对称加密需要两把密钥:公钥和私钥,他们是一对,如果用公钥对数据加密,那么只能用对应的私钥解密。如果用私钥对数据加密,只能用对应的公钥进行解密。因为加密和解密用的是不同的密钥,所以称为非对称加密。 2....
  • 对称加密与非对称加密算法

    千次阅读 2022-01-24 16:25:55
    1.2、对称加密算法 1.2.1、DES 1.2.2、3DES 1.2.4、AES 1.2.5、SM1 1.2.6、SM4 1.2.7、RC2 1.2.8、RC4 1.2.9、RC5 说明 2、非对称加密 2.1、非对称加密算法 2.1.1、RSA 2.1.2、ECC 2.1.3、SM2 3、...
  • 本文主要介绍对称加密算法(symmetric encryption algorithm)和非对称加密算法(asymmetric cryptographic algorithm)的相关知识。 1 对称加密算法 1.1 概述 对称加密算法是应用较早的加密算法,技术成熟。 在...
  • C语言DES加密算法程序
  • package main import ( crypto/rand crypto/rsa crypto/x509 encoding/base64 encoding/pem errors fmt io/ioutil ... str := &^%$#@___Oneck___@#$%^& fmt.Println(初始字符串,str) cipherBytes,err := ...
  • 常用加密算法--对称加密算法

    千次阅读 2019-10-26 20:36:11
    DES是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS46.3)。DES一直以来被美国以及其他国家的政府和银行等广泛使用。然而,随着计算机的进步,现在DES已经能够被暴力破解,强度大不如前了 ...
  • visual c++ vc实现RSA加密算法是最常用的非对称加密算法.zip
  • 一、常用的对称加密算法有 DES:特点是每隔7位做一次奇偶校验,加密时8个字节为一组,得到的密文长度不变 3DES:三重DES 加密过程为 加密-解密-加密(不是加密-加密-加密,是为了兼容以前的DES) 特点:安全,...
  • 设计DES对称加密算法,利用它对简单的密码序列进行对称加密
  • 基于Java的对称加密算法和非对称加密算法

    千次阅读 多人点赞 2022-07-24 21:38:04
    A将对称加密算法中的某种算法(例如AES)再次进行加密(例如RSA)并发给B,B用RSA解密再用AES。填充在分组密码中,当数据长度不符合分组长度时,需要按一定的方式,将尾部明文分组进行填充,这种将尾部分组数据填满...
  • 五种对称加密算法总结

    千次阅读 2021-09-08 13:49:26
    对称加密算法的基石,具有学习价值 密钥长度56(JDK)、56/64(BC) 2、DESede(三重DES) 早于AES出现来替代DES 计算密钥时间太长、加密效率不高,所以也基本上不用 密钥长度112/168(JDK)、128/192(BC) 3、...
  • RSA非对称加密算法加密
  • AES/DES 对称加密算法

    2018-12-25 14:04:55
    DES、AES对称加密算法,之前从网上找的,但是在MAC上运行发现每次加密出来的结果都不一样,后来查了一些博客,最后确认是SecureRandom的随机算法问题,需要设置setSeed.
  • Java字符串的hashcode()就是一个哈希算法,输入任意字符串,输出固定的4字节int整数。碰撞是不能避免的,因为哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。2.不同的输入大概率得到不同...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,164
精华内容 36,065
热门标签
关键字:

对称算法的加密模式