JAVA和.NET的系统类库里都有封装DES对称加密的实现方式,但是对外暴露的接口却各不相同,甚至有时会让自己难以解决其中的问题,比如JAVA加密后的结果在.NET中解密不出来等,由于最近项目有跨JAVA和.NET的加解密,经过我的分析调试,终于让它们可以互相加密解密了。
DES加密
DES是一种对称加密(Data Encryption Standard)算法,以前我写过一篇文章:.NET中加密解密相关知识,有过简单描述。
DES算法一般有两个关键点,第一个是加密算法,第二个是数据补位。
加密算法常见的有ECB模式和CBC模式:
ECB模式:电子密本方式,这是JAVA封装的DES算法的默认模式,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,则补足8个字节(注意:这里就涉及到数据补位了)进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
CBC模式:密文分组链接方式,这是.NET封装的DES算法的默认模式,它比较麻烦,加密步骤如下:
1、首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,就涉及到数据补位了)
2、第一组数据D1与向量I异或后的结果进行DES加密得到第一组密文C1(注意:这里有向量I的说法,ECB模式下没有使用向量I)
3、第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
4、之后的数据以此类推,得到Cn
5、按顺序连为C1C2C3......Cn即为加密结果。
数据补位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding实际只是协议不一样,根据相关资料说明:PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。但是封装的DES算法默认都是8字节,所以可以认为他们一样。数据补位实际是在数据不满8字节的倍数,才补充到8字节的倍数的填充过程。
NoPadding填充方式:算法本身不填充,比如.NET的padding提供了有None,Zeros方式,分别为不填充和填充0的方式。
PKCS7Padding(PKCS5Padding)填充方式:为.NET和JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:
加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。
.NET中的DES加密
对于.NET,框架在System.Security.Cryptography命名空间下提供了DESCryptoServiceProvider作为System.Security.Cryptography.DES加密解密的包装接口,它提供了如下的4个方法:
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
public override void GenerateIV()
public override void GenerateKey()
从.NET类库封装情况,加解密需要传入一个Key和IV向量。而且Key必须为8字节的数据,否则会直接抛异常出来,当使用ECB模式下,不管传入什么IV向量,加密结果都一样。示例代码如下:
public static string EncryptWithJava(string key, string str)
{
if (key.Length < 8 || string.IsNullOrEmpty(str))
{
throw new Exception("加密key小于8或者加密字符串为空!");
}
byte[] bKey = Encoding.UTF8.GetBytes(key.Substring(0,
);
byte[] bIV = IV;
byte[] bStr = Encoding.UTF8.GetBytes(str);
try
{
DESCryptoServiceProvider desc = new DESCryptoServiceProvider();
desc.Padding = PaddingMode.PKCS7;//补位
desc.Mode = CipherMode.ECB;//CipherMode.CBC
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream cStream = new CryptoStream(mStream, desc.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))
{
cStream.Write(bStr, 0, bStr.Length);
cStream.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
byte[] res = mStream.ToArray();
foreach (byte b in res)
{
ret.AppendFormat("{0:x2}", b);
}
return ret.ToString();
}
}
}
catch
{
return string.Empty;
}
}
由于为ECB模式,因此IV这里设置什么值都是可以的,当为CBC模式下,则需要设置为其他值,比如:public static byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },才能正常加密解密。
JAVA中的DES加密
JAVA的javax.crypto.Cipher包下,提供了加密解密的功能,它的静态getInstance方法,可以返回一个Cipher对象,一般有public static final Cipher getInstance(String transformation)方法,transformation为:algorithm/mode/padding,分别表示算法名称,比如DES,也可以在后面包含算法模式和填充方式,但也可以只是算法名称,如为:"DES/CBC/PKCS5Padding","DES"等。JAVA中默认的算法为ECB,默认填充方式为PKCS5Padding。Cipher的Init方法用来初始化加密对象,常见的有:
public final void init(int opmode, Key key, AlgorithmParameterSpec params) ,
public final void init(int opmode,Key key, SecureRandom random),用SecureRandom时,一般用于不需要IV的算法模式,示例代码如下:
public static String encrypt2(String src) throws Exception {
SecureRandom sr = new SecureRandom();
DESKeySpec ks = new DESKeySpec(KEY.getBytes("UTF-8"));
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(ks);
Cipher cip = Cipher.getInstance("DES/CBC/PKCS5Padding");//Cipher.getInstance("DES");
IvParameterSpec iv2 = new IvParameterSpec(IV);
cip.init(Cipher.ENCRYPT_MODE, sk, iv2);//IV的方式
//cip.init(Cipher.ENCRYPT_MODE, sk, sr);//没有传递IV
String dest = byteToHex(cip.doFinal(src.getBytes("UTF-8")));
return dest;
}
当默认用DES,JAVA会用ECB模式,因此这里IV向量没有作用,这里,但当用CBC模式下,如果还是用SecureRandom,则每次加密的结果都会不一样,因为JAVA内部会用随机的IV来初始化Cipher对象,如示例代码,由于Cipher.getInstance("DES/CBC/PKCS5Padding")使用了CBC,因此我这里用的javax.crypto.spec.IvParameterSpec包下的IvParameterSpec来初始化向量IV:
Private final static byte[] IV = new byte[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
总结
对于.NET和JAVA在使用DES对称加密时,需要大家指定一样的算法和填充模式,并且JAVA在写DES加解密算法时,还需要根据创建Cipher对象的不同,正确使用IV向量。在不同系统需要互相数据时,必须要明确的是加密算法,Key和算法模式,再根据不同模式是否需要IV向量,最后是填充模式。
本文是经过自己翻阅资料和反复调试代码而出来的,如有问题,请指正。
分享到:
相关推荐
DES(Data Encryption Standard)是一种对称加密算法,广泛应用于数据安全领域。在Java和.NET平台上,我们可以使用内置的加密库实现DES加密和解密。本文将详细介绍如何在Java和.NET中实现互操作的DES加密解密,并...
常见的加密算法有对称加密(如AES、DES)和非对称加密(如RSA、ECC)。对称加密使用相同的密钥进行加密和解密,而非对称加密则需要一对公钥和私钥,公钥用于加密,私钥用于解密。 2. **Java加密**: 在Java中,...
DES(Data Encryption Standard)是一种对称加密算法,用于保护数据的隐私和安全性。在Java和.NET之间进行互通时,DES加密解密的实现是至关重要的,因为这允许两个平台之间的应用程序能够共享加密过的数据并正确地...
对称加密算法如DES(Data Encryption Standard)、3DES(Triple DES)等,其特点是加密和解密使用同一密钥。这种加密方式速度快,适合大量数据的加密,但密钥管理是个挑战,因为密钥必须在加密和解密双方安全地传递...
1. **对称加密**:如AES(Advanced Encryption Standard),它使用相同的密钥进行加密和解密,速度快但密钥分发是个挑战。 2. **非对称加密**:如RSA,使用一对公钥和私钥,公钥用于加密,私钥用于解密,解决了密钥...
Java中的DES(Data Encryption Standard)是一种广泛使用的对称加密算法,它基于64位的数据块进行操作,并使用56位的密钥。由于其相对简单的实现和较快的加密速度,DES在很多场景下仍被采用,尽管其密钥长度相对较短...
DES(Data Encryption Standard)是一种广泛使用的对称加密算法,尤其在过去的很多年里,它在Java编程中扮演了关键角色。本实例主要探讨如何在Java环境中利用DES算法进行私钥对称加密。以下是关于这个主题的详细讲解...
3Des对称加密在JS实现,此处代码要与https://blog.csdn.net/yufang131/article/details/79869964文章一起看(只包含JS部分)。《三重Des对称加密在JS、Android、Ios 和Java 平台的实现(多加一个JS实现)》
DES是一种对称加密算法,即加密和解密使用相同的密钥。它最初由IBM开发,并于1977年被美国国家标准局(NBS,现在的NIST)采纳为联邦信息处理标准(FIPS)。DES算法采用64位块大小和56位密钥长度。由于密钥较短,DES已经...
3DES(Triple Data Encryption Standard)是一种广泛使用的对称加密算法,它增强了原有的DES(Data Encryption Standard)算法的安全性,通过三次应用相同的密钥来加密数据。本资源提供的是一套完整的JavaScript实现...
DES是一种对称加密算法,它使用相同的密钥进行加密和解密。在Java中,可以使用`javax.crypto`包下的`Cipher`类来实现DES加密。首先,需要创建一个DES密钥,然后使用`Cipher`的`init`方法初始化,并通过`doFinal`...
在IT领域,数据的安全传输和存储常常依赖于加密技术,其中DES(Data Encryption Standard)是一种广泛应用的对称加密算法。本篇文章将详细讲解如何在Java、C#和PHP这三个不同的编程语言环境中实现DES加密,并确保...
DES是一种广泛使用的对称加密算法,以其高效性和安全性在很多应用场景中被采用。 首先,DES加密算法的基本原理是通过一个密钥对明文数据进行操作,将其转换为无法直接识别的密文。在Java中,我们可以利用`javax....
DES是一种对称加密算法,它的全称为数据加密标准,由IBM公司于1970年代初开发,并在1977年被美国国家标准局采纳为联邦信息处理标准FIPS PUB 46。此算法基于一个56位的密钥,通过一系列复杂的数学运算对明文进行加密...
总的来说,这份源码提供了一个使用Java实现DES加密算法的例子,适用于学习和理解对称加密的基本原理和Java的相关API用法。对于学习者来说,通过阅读和分析这些代码,可以加深对DES算法和Java加密库的理解,同时也能...
1. **DES(数据加密标准)**:DES是一种对称加密算法,它使用56位的密钥对数据进行64位的块加密。在Java中,DES的实现主要依赖于`javax.crypto.Cipher`和`java.security.Key`类。首先,需要创建一个`SecretKeySpec`...
1. **对称加密**:对称加密使用同一密钥进行加密和解密,如DES、3DES、AES等。Java中,`javax.crypto.Cipher`类提供了对这些对称加密算法的支持。 2. **非对称加密**:非对称加密使用一对公钥和私钥,一方用公钥...
DES是一种经典的对称加密算法,它使用一个56位的密钥来对数据进行加密和解密。 在Java部分,提供了一个名为`encrypt`的静态方法,该方法用于加密输入的字符串。首先,它使用`java.net.URLEncoder.encode`对输入值...
1. **DES加密算法**:DES是一种对称加密算法,即加密和解密使用相同的密钥。它的密钥长度为64位,实际有效密钥长度为56位。 2. **加密模式选择**:C#中使用了ECB(电子密码本模式),这是一种简单的块加密模式,每个...
在实际应用中,开发者可能会结合SSL/TLS协议进行网络通信加密,使用Java的java.net和javax.net.ssl包提供的类,如SSLSocket和SSLServerSocket,确保数据在网络传输过程中的安全性。 总之,这个Java加密程序源代码...