.NET中的DES对称加密
DES是一种对称加密(Data Encryption Standard)算法 于 年得到美国 *** 的正式许可 是一种用 位密钥来加密 位数据的方法 一般密码长度为 个字节 其中 位加密密钥 每个第 位都用作奇偶校验
DES算法一般有两个关键点 第一个是加密模式 第二个是数据补位 加密模式的主要意义就是 加密算法是按块进行加密的 例如 DES 是 Bit 一个块的进行加密 就是每次加密 个字节 因此每次输入八个字节的明文输出八个字节密文 如果是 个字节 那么分成两个块依次进行加密 问题就出现在这里 如果明文是 分块分别进行加密 那么加密的结果类似 C C C C C C 可以看出明文的规律 这就是 ECB 加密模式 密文可以看出明文的规律 为了解决这个问题 有了其他的加密模式 CBC 加密模式(密码分组连接) CFB加密模式(密码反馈模式) OFB加密模式(输出反馈模式)CBC 是要求给一个初始化的向量 然后将每个输出与该向量作运算 并将运算的结果作为下一个加密块的初始化向量 CFB 和 OFB 则不需要提供初始化向量 直接将密码或者输出作为初始化向量进行运算 这样就避免了明文的规律出现在密文中 当然缺点是解密时需要保证密文的正确性 如果网络传输时发生了一部分错误 则后面的解密结果就可能是错误的 (ECB模式仅影响传输错误的那个块 密码算法基本上都是分组(按快)进行加密的 如果密文长度不是刚刚好可以进行分组 怎么办?只能进行填充
加密算法常见的有ECB模式和CBC模式
第一种电子密本方式(ECB)
ECB模式 电子密本方式 就是将数据按照 个字节一段进行DES加密或解密得到一段 个字节的密文或者明文 最后一段不足 个字节 则补足 个字节(注意 这里就涉及到数据补位了)进行计算 之后按照顺序将计算所得的数据连在一起即可 各段数据之间互不影响 将明文分成n个 比特分组 如果明文长度不是 比特的倍数 则在明文末尾填充适当数目的规定符号 对明文组用给定的密钥分别进行加密 行密文C=(C C …… Cn )其中Ci=DES(K xi) i= …… n 这是Java封装的DES算法的默认模式
第二种密文分组链接方式(CBC)
密文分组链接方式 在CBC方式下 每个明文组xi在加密前与先一组密文按位模二加后 再送到DES加密 CBC方式克服了ECB方式报内组重的缺点 但由于明文组加密前与一组密文有关 因此前一组密文的错误会传播到下一组 这是 NET封装的DES算法的默认模式 它比较麻烦 加密步骤如下
首先将数据按照 个字节一组进行分组得到D D ……Dn(若数据不是 的整数倍 就涉及到数据补位了)
第一组数据D 与向量I异或后的结果进行DES加密得到第一组密文C (注意 这里有向量I的说法 ECB模式下没有使用向量I)
第二组数据D 与第一组的加密结果C 异或以后的结果进行DES加密 得到第二组密文C
之后的数据以此类推 得到Cn
按顺序连为C C C ……Cn即为加密结果
第三种密文反馈方式(CFB) 可用于序列密码
明文X=(x x …… xn ) 其中xi由t个比特组成 第四种输出反馈方式(OFB) 可用于序列密码
与CFB唯一不同的是OFB是直接取DES输出的t个比特 而不是取密文的t个比特 其余都与CFB相同 但它取的是DES的输出 所以它克服了CFB的密文错误传播的缺点
数据补位一般有NoPadding和PKCS Padding(Java中是PKCS Padding)填充方式 PKCS Padding和PKCS Padding实际只是协议不一样 根据相关资料说明 PKCS Padding明确定义了加密块是 字节 PKCS Padding加密快可以是 之间 但是封装的DES算法默认都是 字节 所以可以认为他们一样 数据补位实际是在数据不满 字节的倍数 才补充到 字节的倍数的填充过程
NoPadding填充方式 算法本身不填充 比如 NET的padding提供了有None Zeros方式 分别为不填充和填充 的方式
PKCS Padding(PKCS Padding)填充方式 为 NET和Java的默认填充方式 对加密数据字节长度对 取余为r 如r大于 则补 r个字节 字节为 r的值 如果r等于 则补 个字节 比如
加密字符串为为AAA 则补位为AAA ;加密字符串为BBBBBB 则补位为BBBBBB ;加密字符串为CCCCCCCC 则补位为CCCCCCCC
NET中的DES加密
对于 NET 框架在System Security Cryptography命名空间下提供了DESCryptoServiceProvider作为System Security Cryptography DES加密解密的包装接口 它提供了如下的 个方法
public override ICryptoTransform CreateDecryptor(byte[] rgbKey byte[] rgbIV)
public override ICryptoTransform CreateEncryptor(byte[] rgbKey byte[] rgbIV)
public override void GenerateIV()
public override void GenerateKey()
lishixinzhi/Article/program/net/201311/13492