一、分组密钥算法工作模式

1、电子密码本模式-ECB

ECB是最基本、最容易理解的工作模式。每次加密产生独立的密文分组,每组加密结果不会对其他分组产生影响,相同的明文加密后产生相同的密文,无初始化向量。工作模式如下:

Androidstudio加密apk android 三种常用的加密方式_初始化

优缺点:

Androidstudio加密apk android 三种常用的加密方式_Androidstudio加密apk_02

### 2、密文链接模式-CBC(已丧失安全性,不推荐使用)

明文加密前先与上一组的密文进行异或运算(XOR)后再加密,第一个分组明文与初始向量进行异或运算。选择不同的初始向量生成的密文不一样。工作模式如下:

Androidstudio加密apk android 三种常用的加密方式_Androidstudio加密apk_03

优缺点:

Androidstudio加密apk android 三种常用的加密方式_初始化_04

### 3、密文反馈模式-CFB

对初始化向量加密后与第一个明文分组异或产生第一组密文,第一组密文加密后与第二个明文分组异或产生第二组密文。注意:明文分组并没有通过加密算法直接进行加密,明文分组和密文分组之间只有一个异或。工作模式如下:

Androidstudio加密apk android 三种常用的加密方式_工作模式_05

优缺点:

Androidstudio加密apk android 三种常用的加密方式_工作模式_06

### 4、输出反馈式-OFB

对初始化向量加密后与第一个明文分组异或产生第一组密文,对第一步初始化向量的密文加密后与第二个明文分组异或产生第二组密文。工作模式如下:

Androidstudio加密apk android 三种常用的加密方式_数据_07

优缺点:

Androidstudio加密apk android 三种常用的加密方式_初始化_08

5、计数器模式-CTR

Androidstudio加密apk android 三种常用的加密方式_数据_09

工作模式如下:

Androidstudio加密apk android 三种常用的加密方式_数据_10

优缺点:

Androidstudio加密apk android 三种常用的加密方式_Androidstudio加密apk_11

## 二、分组加密填充方式

1、PKCS5Padding

假设BlockSize是8字节(64bit):

例子1:

待加密数据原长度为1字节:

0x41

填充后:

0x41 0x07 0x07 0x07 0x07 0x07 0x07 0x07

例子2:

待加密数据原长度为2字节:

0x41 0x41

填充后:

0x41 0x41 0x06 0x06 0x06 0x06 0x06 0x06

例子3:

待加密数据原长度为8字节:

0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41

填充后:

0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08

注意:当待加密数据长度恰好是8的整数倍,也是要在后面多增加8个字节,每个字节是0x08。

为什么长度是8的整数倍还需要填充呢?

假设当x是8的整数倍时,不多填充8个0x08。当解密后,我看到解密后的数据的末尾的最后一个字节恰好是0x01,那这个字节是填充上去的还是本身就有的数据呢?

2、PKCS7Padding

PKCS5Padding在填充方面,是PKCS7Padding的一个子集:

PKCS5Padding只是对于8字节(BlockSize=8)进行填充,填充内容为0x01-0x08;

但是PKCS7Padding不仅仅是对8字节填充,其BlockSize范围是1-255字节。

所以,PKCS#5可以向上转换为PKCS7Padding,但是PKCS7Padding不一定可以转换到PKCS5Padding(用PKCS7Padding填充加密的密文,用PKCS5Padding解出来是错误的)。

3、ISO10126

ISO10126 在填充时首先获取需要填充的字节长度 = (块长度 - (数据长度 % 块长度)), 在填充字节序列中最后一个字节填充为需要填充的字节长度值, 填充字节中其余字节均填充随机数值。例子如下:

假定块长度为 16,数据长度为 9,则填充字节数等于7,

数据是:

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

填充后数据是:

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x73 0x68 0xC4 0x81 0xA6 0x23 0x07

4、ZeroPadding

ZeroPadding在填充时首先获取需要填充的字节长度 = (块长度 - (数据长度 % 块长度)), 在填充字节序列中所有字节填充为0x00,零填充在数据最后字节为零的时候可能不可逆。

例:

假定块长度为 8,数据长度为 2,则填充字节数等于 6,

数据是:

0xFF 0xFF

填充后数据:

0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00

5、NoPadding

不填充。这种模式要求被加密数据必须是数据块的整数倍,负责加密会报错。

三、对称加密
1、DES
DES是一种将64比特的明文加密成64比特的密文的对称加密算法。DES的密钥长度是64比特,由于每隔7比特会设置一个用于错误检查的比特,因此实质上密钥长度是56比特。
DES每次只能加密64比特的数据,如果明文比较长就需要以64比特的明文为一个单位进行分组,对每一组分别进行加密。
注意:使用Java加密时如果密钥大于64比特自动过滤超过64比特的低位字节

2、3DES

三重DES(triple-DES)是为了增加DES的强度,将DES重复3次所得到的一种密码算法,通常缩写为3DES。注意Java中密钥长度必须是24个字节。加密机制如下图:

Androidstudio加密apk android 三种常用的加密方式_初始化_12

3、AES

AES密钥是128位(16字节)或192位(24字节)或 256位(32字节)。

四、非对称加密

1、PEM

OpenSSL 使用 PEM 文件格式存储证书和密钥。PEM 实质上是 Base64 编码的二进制内容,再加上开始和结束行,如证书文件的-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----。在这些标记外面可以有额外的信息,如编码内容的文字表示。文件是 ASCII 的,可以用任何文本编辑程序打开它们。观察这个示例 PEM 文件。

-----BEGIN CERTIFICATE-----

MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/

MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT

DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow

SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT

GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC

AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF

q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8

SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0

Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA

a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj

/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T

KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==

-----END CERTIFICATE-----

2、PKCS

The Public-Key Cryptography Standards (PKCS)是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。

PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
PKCS#3:定义Diffie-Hellman密钥交换协议。
PKCS#5:描述一种利用从口令派生出来的安全密钥加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息。
PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式。
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息。
PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。
PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥加密信息的属性类型。
PKCS#10:描述证书请求语法[29]。
PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡之类的加密设备。
PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法。
PKCS#13:椭圆曲线密码体制标准。
PKCS#14:伪随机数生成标准。
PKCS#15:密码令牌信息格式标准。
3、RSA
RSA 算法规定:待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:KeySize / 8)。
-11是因为padding占用了11个字节。