des加密向量
using system;
using system.security.cryptography;
using system.io;
using system.text;
public class encryptstringdes {
public static void main(string);
return;
}
// 使用utf8函数加密输入参数
utf8encoding utf8encoding = new utf8encoding();
byte.tochararray());
// 方式一:调用默认的des实现方法des_csp.
des des = des.create();
// 方式二:直接使用des_csp()实现des的实体
//des_csp des = new des_csp();
// 初始化des加密的密钥和一个随机的、8比特的初始化向量(iv)
byte iv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
des.key = key;
des.iv = iv;
// 建立加密流
symmetricstreamencryptor sse = des.createencryptor();
// 使用cryptomemorystream方法获取加密过程的输出
cryptomemorystream cms = new cryptomemorystream();
// 将symmetricstreamencryptor流中的加密数据输出到cryptomemorystream中
sse.setsink(cms);
// 加密完毕,将结果输出到控制台
sse.write(inputbytearray);
sse.closestream();
// 获取加密数据
byte);
}
console.writeline();
//上面演示了如何进行加密,下面演示如何进行解密
symmetricstreamdecryptor ssd = des.createdecryptor();
cms = new cryptomemorystream();
ssd.setsink(cms);
ssd.write(encrypteddata);
ssd.closestream();
byte decryptedchararray = utf8encoding.getchars(decrypteddata);
console.writeline("解密后数据:");
console.write(decryptedchararray);
console.writeline();
}
}
编译:
d:\csharp>csc des_demo.cs
microsoft (r) c# compiler version 7.00.8905
right (c) microsoft corp 2000. all rights reserved.
运行实例:
d:\csharp>des_demo.exe 使用c#编写des加密程序的framework
加密结果:
3d 22 64 c6 57 d1 c4 c3 cf 77 ce 2f d0 e1 78 2a 4d ed 7a a8 83 f9 0e 14 e1 ba 38
7b 06 41 8d b5 e9 3f 00 0d c3 28 d1 f9 6d 17 4b 6e a7 41 68 40
❷ 什么是3DES对称加密算法
DES加密经过下面的步骤
1、提供明文和密钥,将明文按照64bit分块(对应8个字节),不足8个字节的可以进行填充(填充方式多种),密钥必须为8个字节共64bit
填充方式:
当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组长度。
* NoPadding
API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim
* PKCS5Padding
加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8
解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。
例如:加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。
* PKCS7Padding
PKCS7Padding 的填充方式和PKCS5Padding 填充方式一样。只是加密块的字节数不同。PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。
2、选择加密模式
**ECB模式** 全称Electronic Codebook模式,译为电子密码本模式
**CBC模式** 全称Cipher Block Chaining模式,译为密文分组链接模式
**CFB模式** 全称Cipher FeedBack模式,译为密文反馈模式
**OFB模式** 全称Output Feedback模式,译为输出反馈模式。
**CTR模式** 全称Counter模式,译为计数器模式。
3、开始加密明文(内部原理--加密步骤,加密算法实现不做讲解)
image
1、将分块的64bit一组组加密,示列其中一组:将此组进行初始置换(IP置换),目的是将输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位。
2、开始Feistel结构的16次转换,第一次转换为:右侧数据R0和子密钥经过轮函数f生成用于加密左侧数据的比特序列,与左侧数据L0异或运算,
运算结果输出为加密后的左侧L0,右侧数据则直接输出为右侧R0。由于一次Feistel轮并不会加密右侧,因此需要将上一轮输出后的左右两侧对调后才正式完成一次Feistel加密,
3、DES算法共计进行16次Feistel轮,最后一轮输出后左右两侧无需对调,每次加密的子密钥不相同,子密钥是通过秘钥计算得到的。
4、末置换是初始置换的逆过程,DES最后一轮后,左、右两半部分并未进行交换,而是两部分合并形成一个分组做为末置换的输入
DES解密经过下面的步骤
1、拿到密文和加密的密钥
2、解密:DES加密和解密的过程一致,均使用Feistel网络实现,区别仅在于解密时,密文作为输入,并逆序使用子密钥。
3、讲解密后的明文去填充 (padding)得到的即为明文
Golang实现DES加密解密
package main
import (
"fmt"
"crypto/des"
"bytes"
"crypto/cipher"
)
func main() {
var miwen,_= DESEncode([]byte("hello world"),[]byte("12345678"))
fmt.Println(miwen) // [11 42 146 232 31 180 156 225 164 50 102 170 202 234 123 129],密文:最后5位是补码
var txt,_ = DESDecode(miwen,[]byte("12345678"))
fmt.Println(txt) // [104 101 108 108 111 32 119 111 114 108 100]明码
fmt.Printf("%s",txt) // hello world
}
// 加密函数
func DESEncode(orignData, key []byte)([]byte,error){
// 建立密码块
block ,err:=des.NewCipher(key)
if err!=nil{ return nil,err}
// 明文分组,不足的部分加padding
txt := PKCS5Padding(orignData,block.BlockSize())
// 设定加密模式,为了方便,初始向量直接使用key充当了(实际项目中,最好别这么做)
blockMode := cipher.NewCBCEncrypter(block,key)
// 创建密文长度的切片,用来存放密文字节
crypted :=make([]byte,len(txt))
// 开始加密,将txt作为源,crypted作为目的切片输入
blockMode.CryptBlocks(crypted,txt)
// 将加密后的切片返回
return crypted,nil
}
// 加密所需padding
func PKCS5Padding(ciphertext []byte,size int)[]byte{
padding := size - len(ciphertext)%size
padTex := bytes.Repeat([]byte{byte(padding)},padding)
return append(ciphertext,padTex...)
}
// 解密函数
func DESDecode(cripter, key []byte) ([]byte,error) {
// 建立密码块
block ,err:=des.NewCipher(key)
if err!=nil{ return nil,err}
// 设置解密模式,加密模式和解密模式要一样
blockMode := cipher.NewCBCDecrypter(block,key)
// 设置切片长度,用来存放明文字节
originData := make([]byte,len(cripter))
// 使用解密模式解密,将解密后的明文字节放入originData 切片中
blockMode.CryptBlocks(originData,cripter)
// 去除加密的padding部分
strByt := UnPKCS5Padding(origenData)
return strByt,nil
}
// 解密所需要的Unpadding
func UnPKCS5Padding(origin []byte) []byte{
// 获取最后一位转为整型,然后根据这个整型截取掉整型数量的长度
// 若此数为5,则减掉转换明文后的最后5位,即为我们输入的明文
var last = int(origin[len(origin)-1])
return origin[:len(origin)-last]
}
注意:在设置加密模式为CBC的时候,我们需要设置一个初始化向量,这个量的意思 在对称加密算法中,如果只有一个密钥来加密数据的话,明文中的相同文字就会也会被加密成相同的密文,这样密文和明文就有完全相同的结构,容易破解,如果给一个初始化向量,第一个明文使用初始化向量混合并加密,第二个明文用第一个明文的加密后的密文与第二个明文混合加密,这样加密出来的密文的结构则完全与明文不同,更加安全可靠。CBC模式图如下
CBC
3DES
DES 的常见变体是三重 DES,使用 168 位的密钥对资料进行三次加密的一种机制;它通常(但非始终)提供极其强大的安全性。如果三个 56 位的子元素都相同,则三重 DES 向后兼容 DES。
对比DES,发现只是换了NewTripleDESCipher。不过,需要注意的是,密钥长度必须24byte,否则直接返回错误。关于这一点,PHP中却不是这样的,只要是8byte以上就行;而java中,要求必须是24byte以上,内部会取前24byte(相当于就是24byte)。另外,初始化向量长度是8byte(目前各个语言都是如此,不是8byte会有问题)
❸ JAVA和.NET使用DES对称加密的区别
DES加密算法原理:DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位(每组的第8位作为奇偶校验位),产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 轮循环,使用异或,置换,代换,移位操作四种基本运算。
.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向量,加密结果都一样
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的算法模式
总结
对于.NET和JAVA在使用DES对称加密时,需要大家指定一样的算法和填充模式,并且JAVA在写DES加解密算法时,还需要根据创建Cipher对象的不同,正确使用IV向量。在不同系统需要互相数据时,必须要明确的是加密算法,Key和算法模式,再根据不同模式是否需要IV向量,最后是填充模式。
❹ C#与JAVA的DES加密解密
本来就是没有初始化向量这个东西。。。。。可能是C#运行自己提供P盒或者S盒,而java使用ANSI默认的P盒和S盒了。。。你得去看C#的文档说明。。
加密过程本来就是只需要明文和密钥,C#估计只是多给一个参数罢了。。。看看文档去
###################################
什么叫“初始化向量”?我记得上密码学的时候DES里面没有这个概念~~~
DES算法流程就是固定的。可变的只有P盒和S盒。不知道你说的“初始化向量”是不是S盒
加密和解密只是密钥扩展的顺序颠倒,其他算法完全一样。
P盒不是保密的,S盒设计方式保密但是可以在网上美国安全局网站上找到设计好的S盒。
如果你说真有什么“初始化向量”,那可能你用的是前向反馈模式产生序列密码,不过这样的话,保持相同的初始向量也是可能的啊。估计是你程序写的问题。。。而且这样安全性可能你没有办法考证吧。。。
还有。。。你没有搞错吧。。。DES是64位的。。。。你用8位能搞什么。。。
还有。。看样子你是用C#自带的工具来加密的。。。DES概念里面确实没有什么“初始化向量”,具体怎么搞你找密码学的书看看吧。。。
还有一点。。。。是不是C#里面可以选择轮迭次数???默认是16次,还有你要看好是DES还是3DES。
❺ JAVA和.NET使用DES对称加密的区别
如果我说没有区别你会信吗?
但答案还真是这样,两者没有任何区别的,只不过实现的语言代码不同而已。
那么java与dot net之间的DES是否可以通用?答案也是完全通用。无论是Java的DES加密还是dot net的DES回密,均可以使用另一种语言且不限于Java或dot net解密。够明白吗?
DES其实只是一个算法,加密与解密我们都知道算法与密码是分离的。算法是公开的,都可以用,而密码是独立于算法的。所以DES在不同的语言中实现的算法根本就是一样的——也正是因为如此不管何种语言都是通用的(除非伪DES,要知道DES算法网上本身能搜到而且是一个标准,最先是由美国安全部门公开的)
再说一下,为什么有人“通”用不起来的原因。DES其实有CBC之类的参数的,也就是针对加密块选用的不同的加密手段。正是这个参数的原因,不同的语言中使用不同的参数做为默认值,所以使用默认的方式进行让两个串进行加解密肯定是不同的。DES使用一种模式(方法)加密,用另一种模式(方法)进行解密能得到正确的结果吗?一些人不怪自己的学艺不精,反说是两种语言的DES不通用(这也就是为什么网络上会出现诸多说java和dot net的DES加密方法不通用的原因)。
即便是自己使用的DES加密的代码也是通用的(前提你要遵守DES分开算法),但不要“重复实现已经实现的东西(专业术语叫造轮子)”。
附:
DES.Model属性取值
CBC 密码块链 (CBC) 模式引入了反馈。每个纯文本块在加密前,通过按位“异或”操作与前一个块的密码文本结合。这样确保了即使纯文本包含许多相同的块,这些块中的每一个也会加密为不同的密码文本块。在加密块之前,初始化向量通过按位“异或”操作与第一个纯文本块结合。如果密码文本块中有一个位出错,相应的纯文本块也将出错。此外,后面的块中与原出错位的位置相同的位也将出错。
ECB 电子密码本 (ECB) 模式分别加密每个块。这意味着任何纯文本块只要相同并且在同一消息中,或者在用相同的密钥加密的不同消息中,都将被转换成同样的密码文本块。如果要加密的纯文本包含大量重复的块,则逐块破解密码文本是可行的。另外,随时准备攻击的对手可能在您没有察觉的情况下替代和交换个别的块。如果密码文本块中有一个位出错,相应的整个纯文本块也将出错。
OFB 输出反馈 (OFB) 模式将少量递增的纯文本处理成密码文本,而不是一次处理整个块。此模式与 CFB 相似;这两种模式的唯一差别是移位寄存器的填充方式不同。如果密码文本中有一个位出错,纯文本中相应的位也将出错。但是,如果密码文本中有多余或者缺少的位,则那个位之后的纯文本都将出错。
CFB 密码反馈 (CFB) 模式将少量递增的纯文本处理成密码文本,而不是一次处理整个块。该模式使用在长度上为一个块且被分为几部分的移位寄存器。例如,如果块大小为 8 个字节,并且每次处理一个字节,则移位寄存器被分为 8 个部分。如果密码文本中有一个位出错,则一个纯文本位出错,并且移位寄存器损坏。这将导致接下来若干次递增的纯文本出错,直到出错位从移位寄存器中移出为止。
CTS 密码文本窃用 (CTS) 模式处理任何长度的纯文本并产生长度与纯文本长度匹配的密码文本。除了最后两个纯文本块外,对于所有其他块,此模式与 CBC 模式的行为相同。
DES.Padding属性的取值
None 不填充。
PKCS7 PKCS #7 填充字符串由一个字节序列组成,每个字节填充该字节序列的长度。
Zeros 填充字符串由设置为零的字节组成。
ANSIX923 ANSIX923 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节均填充数字零。
ISO10126 ISO10126 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节填充随机数据。
当Mode不同时,解密的内密内容能与相同吗?PaddingMode不同时,解密的内容的结尾部分能相同吗(填充结果只涉及到最后的一个块).所以当不管何种语言使用相同的Mode及PaddingMode时,加解密的结果是相同的(当然不排除部分语言不实现全部的Mode和PaddingMode)但,基本的都是实现了的,所以基本上任何两种语言之间的DES都可以实现相同的加解密结果!而java和dot net中的DES显然指的是算法,两者是相同的,可以随意使用(Java中dot net中的Mode默认值是不同的,一定要设置相同的Mode和PaddingMode才可以的,不要双方都采用默认值,那样真的通不起来)