Android中的AES加密-下

本文为笔记,记录,写记录后为了方便查阅也为了能更好的记住 大部分参考加自己理解

参考,
什么是AES算法?

前言

本章主要是针对AES加密的原理过程进行梳理。不在于细节,了解各个参数和类的功能来帮助我们再加密是更好的选择如何使用加密。

1. 加密过程

1.1 机密核心代码(包含但不仅紧限于)

方法调用

这段代码上文中我们也说过了,大致的核心加密过程就是这些,只不过,在Android要适配不同版本对应的SecureRandom获取方式不同和用KeyStore存储密钥。(SecureRandom这个类其实相当与加盐,将原文密钥经过一些特定的随机加密算法获取新的密钥)。

PS:平时我们可能对字符串进行Base64编码,Base64更偏向于编码而非加密,方便在不同的环境下传输。

不适用AES的过程:

1592381263(1).jpg

使用AES后:

1592381399(1).jpg

1.2 加密过程解释

  1. 发送方(如客户端)通过密钥key对铭文进行加密
  2. 发送方将机密后的密文ZdyCIZjNgxv2TGzxEen9MIY8ZFUwzVk68u2JsWILyac=发送给接收方
  3. 接收方使用相同的密钥key进行解密

AES特点

  1. 对称加密,也就是用收发两方都是用相同的密钥Key加密和解密
  2. AES是DES的升级,在选择上如果使用对称加密更建议使用AES加密
  3. AES是可逆的,特定场景需要不可逆使用MD5等算法

2. 加密参数

加密的核心类是Cipher。通过对代码和加密过程,我们来说明下加密几个概念。

2.1 密钥

密钥,也就是上面所说的密钥Key,在AES中使用明确的要求的:

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

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

他们的特点也就是密钥越长(指密钥的位数),越安全。越短性能越高。他们的本质是在于加密的轮数不同相应的,如何选择看加密的重要性。一般来说用128多点

2.3 分组加密

要想了解填充的概念,我们先要了解AES的分组加密特性。

什么是分组加密呢?我们来看看下面这张图:


分组加密

AES算法在对明文加密的时候,并不是把整个明文一股脑加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。

这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。

但是这里涉及到一个问题:

假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding)。

2.3 填充方式

NoPadding:

不做任何填充,但是要求明文必须是16字节的整数倍

PKCS5Padding(默认):

如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。

比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则补全为{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}

ISO10126Padding:

如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数。

比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则可能补全为{1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6

==这里有2个问题==

  1. 如果使用PKCS5Padding或ISO10126Padding填充方式,切铭文是16的倍数呢?

答:直接再补上16个字节{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}

  1. 如果是明文15位呢?如果用PKCS5Padding填充方式呢?

答: 也会补充一个字节位0x01。

  1. 如果16位铭文格式是这种{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6},那么不会认为后面的6是填充的呢?然会形象最后的解密出来的明文呢?

答:不会,因为能获取明文长度所以,知道后面的6个6是数据而不是填充数据。

PKCS7Padding
Android中特有的,Java中没有,Android没有使用标准Java的AES加密,而是自己实现了一套,顺便实现了PKCS7Padding但是PKCS5Padding可以解密PKCS7Padding加密的数据

2.4 模式

AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:

ECB、CBC、CTR、CFB、OFB

模式之间的主题思想是近似的,在处理细节上有一些差别。我们这一期只介绍各个模式的基本定义。

ECB模式(默认):

电码本模式 Electronic Codebook Book

最早采用和最简单的模式,它将待加密的数据分成若干块,每块的大小跟加密密钥长度相同,然后分别对每个数据块用同一密钥进行加密。

特点: 简单,有利于并行计算(每个数据块用同一密钥单独加密),误差不会传递(一个数据块出错不会影响其他数据块)。

由于所有分组的加密方式一致,明文中的重复内容会在密文中有所体现,因此难以抵抗统计分析攻击。

因此,ECB模式一般只适用于小数据量的字符信息的安全性保护

CBC模式:

密码分组链接模式 Cipher Block Chaining

CBC模式对于每个待加密的密码块在加密前会先与前一个密码块的密文异或,然后再用加密器加密。第一个明文块与一个叫初始化向量的数据块异或。

特点:CBC模式相比ECB有更高的保密性,适合传输长的报文,但由于对每个数据块的加密依赖与前一个数据块的加密所以加密无法并行,误差也会传递,与ECB一样,不是很适合对流数据进行加密。需要初始化向量。

CTR模式:

计算器模式 Counter

CFB模式:

密码反馈模式 Cipher FeedBack

OFB模式:

输出反馈模式 Output FeedBack

后面几个不常用。

方法调用
  1. kgen.init传入的第一个参数128决定了密钥的长度是128bit。

  2. Cipher.getInstance("AES/CBC/NoPadding")决定了AES选择的填充方式是NoPadding,工作模式是CBC模式。

几点补充:

1.我们在调用封装好的AES算法时,表面上使用的Key并不是真正用于AES加密解密的密钥,而是用于生成真正密钥的“种子”。

2.填充明文时,如果明文长度原本就是16字节的整数倍,那么除了NoPadding以外,其他的填充方式都会填充一组额外的16字节明文块。

2. 底层原理

2.1 加密原理

底层原理

在这里我们重新梳理一下:

1.把明文按照128bit拆分成若干个明文块。

2.按照选择的填充方式来填充最后一个明文块。

3.每一个明文块利用AES加密器和密钥,加密成密文块。

4.拼接所有的密文块,成为最终的密文结果。

AES 不是一次性加密所有铭文块,而是经过很多轮数的加密,加密的轮数,取决与密钥的长度

具体分成多少轮呢

初始轮(Initial Round) 1次

普通轮(Rounds) N次

最终轮(Final Round) 1次

可以看到无论多少轮,不同的是普通论的个数

AES的Key支持三种长度:AES128,AES192,AES256。Key的长度决定了AES加密的轮数(也就是普通论的个数)。

除去初始轮,各种Key长度对应的轮数如下:

AES128:10轮

AES192:12轮

AES256:14轮

不同阶段的Round有不同的处理步骤。

初始轮只有一个步骤

加轮密钥(AddRoundKey)

普通轮有四个步骤

字节代替(SubBytes)

行移位(ShiftRows)

列混淆(MixColumns)

加轮密钥(AddRoundKey)

最终轮有三个步骤:

字节代替(SubBytes)

行移位(ShiftRows)

加轮密钥(AddRoundKey)

字节代替(SubBytes
将明文块分成4x4 16字节的数组,将每个数组的字节换成另外一个字节

image

行移位(ShiftRows)
第一行不变

第二行循环左移1个字节

第三行循环左移2个字节

第四行循环左移3个字节

image

列混淆(MixColumns)

输入数组的每一列要和一个名为修补矩阵(fixed matrix)的二维常量数组做矩阵相乘,得到对应的输出列。

image

加轮密钥(AddRoundKey)

image

唯一利用到密钥的一步,128bit的密钥也同样被排列成4X4的矩阵。
让输入数组的每一个字节a[i,j]与密钥对应位置的字节k[i,j]异或一次,就生成了输出值b[i,j]。
需要补充一点,加密的每一轮所用到的密钥并不是相同的。这里涉及到一个概念:扩展密钥(KeyExpansions)。

扩展密钥(KeyExpansions)

AES源代码中用长度 4 x 4 x(10+1指的是不管密钥长度是多少,加密轮数是多少都有1次初始轮加密,10代表128字节密钥key) 字节的数组W来存储所有轮的密钥。W{0-15}的值等同于原始密钥的值,用于为初始轮做处理。

后续每一个元素W[i]都是由W[i-4]和W[i-1]计算而来,直到数组W的所有元素都赋值完成。

W数组当中,W{0-15}用于初始轮的处理,W{16-31}用于第1轮的处理,W{32-47}用于第2轮的处理 ......一直到W{160-175}用于最终轮(第10轮)的处理。

总结:我们写入的密钥只有在初始轮加密用到,之后每次加密轮用的密钥都是基于初始轮W[0-15]之后按照规则计算出来的

2.2 模式原理

模式不同其实对应的明文块与明文块之间的工作模式的。上面的加密逻辑是单个明文块的加密逻辑。模式是在整个明文块加密过程中起作用,更宏观一点。加密原理是每个明文块内部。 两个互相不影响

1.ECB模式

ECB模式(Electronic Codebook Book)是最简单的工作模式,在该模式下,每一个明文块的加密都是完全独立,互不干涉的。

image

这样的好处是什么呢?

1.简单

2.有利于并行计算

缺点同样也很明显:

相同的明文块经过加密会变成相同的密文块,因此安全性较差。

2.CBC模式

CBC模式(Cipher Block Chaining)引入了一个新的概念:初始向量IV(Initialization Vector)。

IV是做什么用的呢?它的作用和MD5的“加盐”有些类似,目的是防止同样的明文块始终加密成同样的密文块。

image

从图中可以看出,CBC模式在每一个明文块加密前会让明文块和一个值先做异或操作。IV作为初始化变量,参与第一个明文块的异或,后续的每一个明文块和它前一个明文块所加密出的密文块相异或。

这样以来,相同的明文块加密出的密文块显然是不一样的。

CBC模式的好处是什么呢?
安全性更高

坏处也很明显:
1.无法并行计算,性能上不如ECB
2.引入初始化向量IV,增加复杂度。

CBC模式代码加密:

     /**
     * AES加密
     *
     * @param content
     * @return
     */
    public EncryptData aesEncrypt(String alias, String content) {
        try {
            SecretKey secretKey = getSecretKey(keyStore);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] bytes = cipher.doFinal(StringUtils.string2Bytes(content));
            byte[] iv = cipher.getIV();
            String encryptString = Base64.encodeToString(bytes, Base64.NO_WRAP);
            return new EncryptData(alias, encryptString, iv);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * AES解密
     *
     * @param encryptData
     * @return
     */
    public String aesDecrypt(EncryptData encryptData) {
        try {
            SecretKey secretKey = getSecretKey(keyStore);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(encryptData.getIv()));
            byte[] bytes = cipher.doFinal(Base64.decode(encryptData.getEncryptString()
                    , Base64.NO_WRAP));
            return StringUtils.bytes2String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
        
        //EncryptData是自己实体,用于保存向量和数据 
        //KeyStore上篇文章有写如何创建

用向量加密,也要用相同的向量解密,所以可以把向量保存起来。

更多内容 :

https://blog.csdn.net/dodod2012/article/details/80824580

什么是MD5算法?

如何破解MD5算法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342