一、加密基础
学习如何使用加密之前,我们需要了解一些加密相关的基础知识。加密算法一般分为两种:对称加密算法和非对称加密算法。
1、对称加密
对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密,获取信息。常见的对称加密算法有:des/aes/3des.
对称加密算法的特点有:速度快,加密前后文件大小变化不大,但是密匙的保管是个大问题,因为消息发送方和接收方任意一方的密匙丢失,都会导致信息传输变得不安全。
2、非对称加密
与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙自己安全保存,而将公匙公开。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。发送数据前只需要使用接收方的公匙加密就行了。常见的非对称加密算法有RSA/DSA:
非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候我们还需要对大块数据进行分块加密。
3、数字签名
为了保证数据的完整性,还需要通过散列函数计算得到一个散列值,这个散列值被称为数字签名。其特点有:
无论原始数据是多大,结果的长度相同的;
输入一样,输出也相同;
对输入的微小改变,会使结果产生很大的变化;
加密过程不可逆,无法通过散列值得到原来的数据;
常见的数字签名算法有md5,hash1等算法。
二、RSA加密明文长度
提到密钥,我们不得不提到RSA的三个重要大数:公钥指数e、私钥指数d和模值n。
1、一次能加密的明文长度与密钥长度成正比:
len_in_byte(raw_data) = len_in_bit(key)/8 -11,如 1024bit 的密钥,一次能加密的内容长度为 1024/8 -11 = 117 byte。
所以非对称加密一般都用于加密对称加密算法的密钥
,而不是直接加密内容。
2、明文长度117字节问题
明文长度小于等于密钥长度 128Bytes - 11 这个说法本身不太准确,会让人产生 RSA 1024 只能加密 117 字节长度明文的误解。实际上,RSA 算法本身要求加密内容也就是明文长度 m 必须满足 0<m<n,也就是说内容这个大整数不能超过 n,否则就出错。
那么如果 m=0 是什么结果?
普遍 RSA 加密器会直接返回全 0 结果,如果 m>n,运算就会出错。
因此,RSA 实际可加密的明文长度最大也是 1024bits,但问题就来了:
如果小于这个长度怎么办?
就需要进行 padding,因为如果没有 padding 用户无法确分解密后内容的真实长度,字符串之类的内容问题还不大,以 0
作为结束符,便于区分。
但对二进制数据就很难理解,因为不确定后面的 0
是内容还是内容结束符。
只要用到 padding,那么就会占用实际的明文长度,我们一般使用的 padding 标准有 NoPPadding、OAEPPadding、PKCS1Padding 等。其中 PKCS#1 建议的 padding 就占用了 11 个字节,于是才有 117 字节的说法。
如果大于这个长度怎么办?
很多算法的 padding 往往是在后边的,但 PKCS 的 padding 则是在前面的,此为有意设计,有意的把第一个字节置0
以确保 m 的值小于 n。
这样,128字节(1024bits)- 11 字节正好是117字节,但对于 RSA 加密来讲,padding 也是参与加密的。所以,依然按照 RSA 1024 实际的明文只有 117 字节。
关于 PKCS#1 padding 规范可参考:RFC2313 chapter 8.1。
我们在把明文送给 RSA 加密器前,要确认这个值是不是大于 n,也就是如果接近 n 位长,那么需要先 padding 再分段加密
。
除非我们是“定长定量自己可控可理解”的加密则不需要 padding。
三、秘文长度
加密后密文的长度为密钥的长度,如密钥长度为 1024b(128Byte),最后生成的密文固定为 1024b(128Byte)
密文长度就是给定符合条件的明文加密出来的结果位长,这个可以确定,加密后的密文位长跟密钥的位长度是相同的
,因为加密公式:
C=(P^e)%n
所以,C 最大值就是 n-1,所以不可能超过 n 的位数。
尽管可能小于 n 的位数,但从传输和存储角度,仍然是按照标准位长来进行的。因此,即使我们加密一字节的明文,运算出来的结果也要按照标准位长来使用。
参考
1、PENSSL库的使用-DES篇
2、PHP的openssl加密扩展使用小结
3、RSA密钥长度、明文长度和密文长度
4、浅析DES与AES、RSA三种典型加密算法的比较
5、【IoT】加密与安全:非对称加密算法 RSA 1024 公钥、秘钥、明文和密文长度