AES加密模式详解.docx
- 文档编号:8195365
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:15
- 大小:424.14KB
AES加密模式详解.docx
《AES加密模式详解.docx》由会员分享,可在线阅读,更多相关《AES加密模式详解.docx(15页珍藏版)》请在冰豆网上搜索。
AES加密模式详解
一般的加密通常都是块加密,如果要加密超过块大小的数据,就需要涉及填充和链加密模式,文中提到的ECB和CBC等就是指链加密模式。
在C#组件中实现的很多算法和Java都不太兼容,至少我发现RSA和AES/ECB是如此。
研究了AES/ECB时发现了这篇文档,图还画的不错,先记下。
注意,还缺一种CTR的模式。
对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)
一.AES对称加密:
AES加密
分组
二.分组密码的填充
分组密码的填充
e.g.:
PKCS#5填充方式
三.流密码:
四.分组密码加密中的四种模式:
3.1ECB模式
优点:
1.简单;
2.有利于并行计算;
3.误差不会被传送;
缺点:
1.不能隐藏明文的模式;
2.可能对明文进行主动攻击;
3.2CBC模式:
优点:
1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点:
1.不利于并行计算;
2.误差传递;
3.需要初始化向量IV
3.3CFB模式:
优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.误差传送:
一个明文单元损坏影响多个单元;
3.唯一的IV;
3.4OFB模式:
优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.对明文的主动攻击是可能的;
3.误差传送:
一个明文单元损坏影响多个单元;
TAG:
模式ECBCBCCFBOFB
关于AES算法JAVA同C++互解(AES)收藏
关于加解密JAVA一般使用的JCE,关于C++可以实现AES加解密的开源项目就多的数不胜数的。
理论上上算法一样,对称密钥一样就能够互相识别了。
相信很多人开始想法都同我一样,起初我JAVA用JCE,C++使用openssl。
结果发现加密出的密文完全不相同。
出现问题就要解决
了解了一下JCE:
JCE中AES支持五中模式:
CBC,CFB,ECB,OFB,PCBC;支持三种填充:
NoPadding,PKCS5Padding,ISO10126Padding。
不支持SSL3Padding。
不支持“NONE”模式。
好原来有模式和填充一说。
在OPENSSL中直接有一个CBC加解密函数。
填充没找到,试过后发现C++加密出的内容比JAVA的要长出一截,前面的内容是完全一样的。
这应该就出现在填充上。
本来以为找到问题关键就应该很容易解决的。
结果发现OPENSSL的填充是固定实现的,而我所需要解密的java端代码不能改动。
一条路走不通咱就换条路。
最后发现有一个开源项目Botan什么都有而且同JCE十分相似并且满足我要求垮平台,好就是它了。
附:
算法/模式/填充16字节加密后数据长度不满16字节加密后长度
AES/CBC/NoPadding16不支持
AES/CBC/PKCS5Padding3216
AES/CBC/ISO10126Padding3216
AES/CFB/NoPadding16原始数据长度
AES/CFB/PKCS5Padding3216
AES/CFB/ISO10126Padding3216
AES/ECB/NoPadding16不支持
AES/ECB/PKCS5Padding3216
AES/ECB/ISO10126Padding3216
AES/OFB/NoPadding16原始数据长度
AES/OFB/PKCS5Padding3216
AES/OFB/ISO10126Padding3216
AES/PCBC/NoPadding16不支持
AES/PCBC/PKCS5Padding3216
AES/PCBC/ISO10126Padding3216
可以看到,在原始数据长度为16的整数倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长度等于16*(n+1)。
在不足16的整数倍的情况下,假如原始数据长度等于16*n+m[其中m小于16],除了NoPadding填充之外的任何方式,加密数据长度都等于16*(n+1);NoPadding填充情况下,CBC、ECB和PCBC三种模式是不支持的,CFB、OFB两种模式下则加密数据长度等于原始数据长度。
本文来自CSDN博客,转载请标明出处:
PKCS5Padding
最近跟一个同事搞数据加密传输,加密算法用的是des,他用delphi做客户端,我用java做服务器。
java做这个很简单,几句话就写好了,delphi没有现成的类库可以做这个,他从网上下载了一段代码。
一开始很顺利,我的密文他能解,后来发现他的密文我解不了,这下抓瞎了。
后来看des算法的介绍,水平有限,也看不出名堂来
不过反复看了几遍,看到一句“加密的数据不足64位,要补足64位”,突然就想到,会不会是补足的方式不同呢?
反正jce没有源代码,先从delphi看起,果然,在不足8位的时候,他下载的那段代码是用0来填充的。
java填的是几呢?
虽然没有代码,还是可以穷举的,毕竟byte就256个数字,写了个循环,测试了一下,发现了,用“中国”做明文时补的是4个字节的4,用“Edit1”做明文,补充的就是3个字节的3,遂作恍然大悟状,这不是缺几个字节就补几吗。
把delphi代码改了一下,果然没问题了,可是多测了几个明文之后,发现还是有不对的,dfadsfsdfsdfsdfsdakfjlfjsdlks这样的一段跟密文一样的明文,该如何找出问题来?
不过还好有jdk帮助文件,翻查了一下关于Cipher的几个类的说明,注意到了PKCS5Padding这个东西,google一下,恍然大悟,原来在恰好8个字节时还要补8个字节的8啊。
说白了,还是知识面太窄,对加密解密的东西不了解啊。
网络传数据时一般要经过加密,较简单的DES对称加密(CRC模式,PKCS7)
==================================================================================
C#(客户端):
usingSystem.Security.Cryptography;
...
///
///进行DES加密。
///
///
///
///
publicstaticstringEncrypt(byte[]bEncrypt,stringsKey)
{
//returnToBase64(bEncrypt);
using(DESCryptoServiceProviderdes=newDESCryptoServiceProvider())//默认为crc,pkcs7
{
//byte[]inputByteArray=Encoding.UTF8.GetBytes(pToEncrypt);
des.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStreamms=newSystem.IO.MemoryStream();
try
{
using(CryptoStreamcs=newCryptoStream(ms,des.CreateEncryptor(),CryptoStreamMode.Write))
{
cs.Write(bEncrypt,0,bEncrypt.Length);
cs.FlushFinalBlock();
cs.Close();
}
}
catch
{
return"";
}
stringstr=Convert.ToBase64String(ms.ToArray());
ms.Close();
returnstr;
}
}
注意这里直接用key当做VI向量,并且默认的padding策略为PKCS7
===================================================================================
JavaWeb服务端:
packagecom.spt.util;
importjavax.crypto.BadPaddingException;
importjavax.crypto.Cipher;
...
publicclassDESTool{
//采用的是DES算法
privateSecretKeysecretKey;//密钥
privateIvParameterSpeciv;//偏移量
privateCipherdecryptCipher;//解密对象
/*
*strKey必须是8位长度的字符串,即64bit。
*/
publicDESTool(StringstrKey){
try{
//指定算法产生解密对象
decryptCipher=Cipher.getInstance("DES/CBC/PKCS5Padding");//选择模式和填充方式,与.NET对应
//由用户密钥产生系统密钥
secretKey=SecretKeyFactory.getInstance("DES").generateSecret(newDESKeySpec(strKey.getBytes("UTF-8")));
//产生偏移量
iv=newIvParameterSpec(strKey.getBytes("UTF-8"));
//加载解密对象
decryptCipher.init(Cipher.DECRYPT_MODE,secretKey,iv);
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
}catch(InvalidKeySpecExceptione){
e.printStackTrace();
}catch(InvalidAlgorithmParameterExceptione){
e.printStackTrace();
}
}
/**
*解密.net平台上C#加密过的字节数组
*
*@paramarrB待解密的字节数组
*@return解密后的字节数组
*@throwsIllegalBlockSizeException
*@throwsBadPaddingException
*/
publicbyte[]decrypt(byte[]arrB)throwsIllegalBlockSizeException,BadPaddingException{
returndecryptCipher.doFinal(arrB);
}
}
==================================================================================
Delphi客户端相应的DES加密
网上流传的一些des算法没有crc预处理和设置iv向量,因此为了上面的web服务端能够解密需要手工做些预处理
unitEncodingUtil;
interface
uses
SysUtils,Classes,Types,EncdDecd,LbCipher;
//输入首地址和长度、key串返回encryptedblock
functionDESEncrypt(pInData:
PByte;dataLen:
Integer;keyStr:
string):
TByteDynArray;
implementation
functionDESEncrypt(pInData:
PByte;dataLen:
Integer;keyStr:
string):
TByteDynArray;
var
temp,res,byteStr,arrStr:
string;
poschar:
char;
Encrypt:
boolean;
key:
TKey64;
i,j,len,strLen,posnum,resLen,index:
integer;
Context:
TDESContext;
block,iv:
TDESBlock;
lastByte,curByte:
Byte;
begin
resLen:
=dataLen+1;
ifresLenmod8<>0then
resLen:
=resLen+(8-(resLenmod8));
SetLength(Result,resLen);
index:
=0;
Encrypt:
=true;
strLen:
=Length(keyStr);
//iv也默认和key一样
fori:
=0to7do
begin
ifi>(strLen-1)then
begin
key[i]:
=0;
iv[i]:
=0
end
else
begin
key[i]:
=byte(keyStr[i+1]);
iv[i]:
=key[i];
end;
end;
InitEncryptDES(Key,Context,Encrypt);
len:
=dataLen;
lastByte:
=Byte(8-(dataLenmod8));
posnum:
=0;
fori:
=0tolendo
begin
if(i=len)then
curByte:
=lastByte
else
curByte:
=(PByte(longint(pInData)+i))^;
block[posnum]:
=curByte;
posnum:
=posnum+1;
ifposnum=8then
begin
EncryptDESCBC(Context,IV,block);//blockmodified
forj:
=0to7do
begin
Result[index]:
=block[j];
index:
=index+1;
end;
iv:
=block;
posnum:
=0;
end;
end;
ifposnum<>0then
begin
fori:
=posnumto7do
begin
block[i]:
=lastByte;
end;
EncryptDESCBC(Context,IV,Block);
forj:
=0to7do
begin
Result[index]:
=block[j];
index:
=index+1;
end;
posnum:
=0;
end;
{
ifindex<>resLenthen
ShowMessage('deserror');
}
end;
end.
参考
PBLockBox下载:
安装:
D7source,lib路径加入控件source,安装packagevc70.dpk
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AES 加密 模式 详解