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才可以的,不要雙方都採用默認值,那樣真的通不起來)