本文目錄一覽:
- 1、Java和.NET使用DES對稱加密的區別
- 2、java 給定十六位密鑰 如何進行des加密?
- 3、JAVA和.NET使用DES對稱加密的區別
- 4、java des 加密 解密 密鑰隨機取得方法
- 5、java des加密,密鑰的長度是多少
Java和.NET使用DES對稱加密的區別
沒有區別,DES只是加密的一種演算法,Java與.NET語言中只是對這種演算法的實現,所以兩者是沒有任何區別的。演算法與密鑰本來就是分開的,演算法本來就是公開的,語言只是對這種演算法的實現而已,在這種情況下DES與語言沒有任何相關性,只有自己的演算法標準。
但很多人反映的Java中的DES/TDES與.NET中的DES/TDES不通用,其實並不存在這樣的問題的。兩者是幾乎完全通用的。所以沒有存在不通用的情況的。
由於語言的實現基於自己的習慣與理解上的不同,不同的語言採用了不同的默認參數(默認值),當然,就算在同種語言下,這些參數不同的時加密與解密也會有所不同的(只會默認默認參數就認為不通用的那些人,真想不通這個問題怎麼提出來的)。
事實上DES除了一個key與iv(初始向量)必須保證相同外,還有對加密的不同解釋參數,如mode與paddingmode。DES加密是是塊加密的一種,在處理塊級與未尾塊級時,有不同的方式(mode)如電子密碼本(CBC)之類的,每個參數有不同的加密行為與意義,當然這只是DES加密標準的一部分,並不能獨立出去的。paddingMode則是則塊加密當最後一個塊不足時的填充方式。而在java與net實現加密或解密時都遵從標準,實現了不同的填充方式以供選擇。但由於每個語言的默認值不同,如net中cbc是默認值,而Java中則是另外一個,填充方式的默認值也不相同,所以會出現不設計這兩個參數時,在java與net通信時無法正確解密。所謂的不Java與net中DES不同,僅僅只是默認參數不同,如果你能正確設置這兩個參數,幾乎任何語言中DES加密與解密都是通用的(部分語言中並沒有全部實現DES中的標準,所以可能會出現特定語言的某種加密方式無法在另一種語言中解析)。
所以,DES本身沒有任何區別,他只是一個標準(你家交流電與他家交流電有什麼區別?),對於不同的實現必須依賴於此標準實現,所以DES標準本身而言是相同的。如果說DES在Java與NET中的類庫實現有什麼區別,那麼兩種語言類庫完全沒可比性(兩個人有什麼區別,一張嘴兩隻眼睛的標準外,怕是沒有相同之處了),而對於DES實現支持上,兩者也是幾乎相同,Java與net均實現了DES標準全部的規範。
最後想說的是,加密學中只介紹DES,並不說在不同語言中的實現,因為任何語言實現都依賴於相同的DES加解密演算法。我覺得這個問題應該問成「在DES在java中與NET中實現的類庫默認值有什麼不同」才對。
java 給定十六位密鑰 如何進行des加密?
package com.palic.pss.afcs.worldthrough.common.util;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import repack.com.thoughtworks.xstream.core.util.Base64Encoder;
/**
* AES加密解密
* @author EX-CHENQI004
*
*/
public class AesUtils {
public static final String cKey= “assistant7654321”;
/**
* 加密–把加密後的byte數組先進行二進位轉16進位在進行base64編碼
* @param sSrc
* @param sKey
* @return
* @throws Exception
*/
public static String encrypt(String sSrc, String sKey) throws Exception {
if (sKey == null) {
throw new IllegalArgumentException(“Argument sKey is null.”);
}
if (sKey.length() != 16) {
throw new IllegalArgumentException(
“Argument sKey’length is not 16.”);
}
byte[] raw = sKey.getBytes(“ASCII”);
SecretKeySpec skeySpec = new SecretKeySpec(raw, “AES”);
Cipher cipher = Cipher.getInstance(“AES”);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(sSrc.getBytes(“UTF-8”));
String tempStr = parseByte2HexStr(encrypted);
Base64Encoder encoder = new Base64Encoder();
return encoder.encode(tempStr.getBytes(“UTF-8”));
}
/**
*解密–先 進行base64解碼,在進行16進位轉為2進位然後再解碼
* @param sSrc
* @param sKey
* @return
* @throws Exception
*/
public static String decrypt(String sSrc, String sKey) throws Exception {
if (sKey == null) {
throw new IllegalArgumentException(“499”);
}
if (sKey.length() != 16) {
throw new IllegalArgumentException(“498”);
}
byte[] raw = sKey.getBytes(“ASCII”);
SecretKeySpec skeySpec = new SecretKeySpec(raw, “AES”);
Cipher cipher = Cipher.getInstance(“AES”);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
Base64Encoder encoder = new Base64Encoder();
byte[] encrypted1 = encoder.decode(sSrc);
String tempStr = new String(encrypted1, “utf-8”);
encrypted1 = parseHexStr2Byte(tempStr);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, “utf-8”);
return originalString;
}
/**
* 將二進位轉換成16進位
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i buf.length; i++) {
String hex = Integer.toHexString(buf[i] 0xFF);
if (hex.length() == 1) {
hex = ‘0’ + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 將16進位轉換為二進位
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
public static void main(String[] args) throws Exception {
/*
* 加密用的Key 可以用26個字母和數字組成,最好不要用保留字元,雖然不會錯,至於怎麼裁決,個人看情況而定
*/
String cKey = “assistant7654321”;
// 需要加密的字串
String cSrc = “123456”;
// 加密
long lStart = System.currentTimeMillis();
String enString = encrypt(cSrc, cKey);
System.out.println(“加密後的字串是:” + enString);
long lUseTime = System.currentTimeMillis() – lStart;
System.out.println(“加密耗時:” + lUseTime + “毫秒”);
// 解密
lStart = System.currentTimeMillis();
String DeString = decrypt(enString, cKey);
System.out.println(“解密後的字串是:” + DeString);
lUseTime = System.currentTimeMillis() – lStart;
System.out.println(“解密耗時:” + lUseTime + “毫秒”);
}
}
JAVA和.NET使用DES對稱加密的區別
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()
java des 加密 解密 密鑰隨機取得方法
java DES 加密 解密 生成隨機密鑰
舉例說明:
//保存生成的key
public static void saveDesKey() {
try {
SecureRandom sr = new SecureRandom();
// 選擇的DES演算法生成一個KeyGenerator對象
KeyGenerator kg = KeyGenerator.getInstance(“DES”);
kg.init(sr);
// 相對路徑 需要新建 conf 文件夾
// String fileName = “conf/DesKey.xml”;
// 絕對路徑
String fileName = “d:/DesKey.xml”;
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 生成密鑰
Key key = kg.generateKey();
oos.writeObject(key);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取生成的key
public static Key getKey() {
Key kp = null;
try {
// 相對路徑 需要新建 conf 文件夾
// String fileName = “conf/DesKey.xml”;
// InputStream is = Encrypt.class.getClassLoader().getResourceAsStream(fileName);
// 絕對路徑
String fileName = “d:/DesKey.xml”;
FileInputStream is = new FileInputStream(fileName);
ObjectInputStream oos = new ObjectInputStream(is);
kp = (Key) oos.readObject();
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
return kp;
}
//加密開始
public static void encrypt(String file, String dest) throws Exception {
Cipher cipher = Cipher.getInstance(“DES”);
cipher.init(Cipher.ENCRYPT_MODE, getKey());
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(dest);
CipherInputStream cis = new CipherInputStream(is, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = cis.read(buffer)) 0) {
out.write(buffer, 0, r);
}
cis.close();
is.close();
out.close();
}
//解密開始
public static void decrypt(String file, String dest) throws Exception {
Cipher cipher = Cipher.getInstance(“DES”);
cipher.init(Cipher.DECRYPT_MODE, getKey());
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(dest);
CipherOutputStream cos = new CipherOutputStream(out, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = is.read(buffer)) = 0) {
cos.write(buffer, 0, r);
}
cos.close();
out.close();
is.close();
}
}
//des加密主方法
public class DES {
public static void main(String[] args) throws Exception {
Encrypt.saveDesKey();
System.out.println(“生成key”);
Encrypt.getKey();
System.out.println(“獲取key”);
Encrypt.encrypt(“d:\\hello.txt”, “d:\\encrypt.txt”);
System.out.println(“加密”);
Encrypt.decrypt(“d:\\encrypt.txt”, “d:\\decrypt.txt”);
System.out.println(“解密”);
}
以上方法親測可用。
java des加密,密鑰的長度是多少
3des演算法是指使用雙長度(16位元組)密鑰k=(kl||kr)將8位元組明文數據塊進行3次des加密/解密。如下所示:
y
=
des(kl)[des-1(kr)[des(kl[x])]]
解密方式為:
x
=
des-1
(kl)[des
(kr)[
des-1
(kl[y])]]
其中,des(kl[x])表示用密鑰k對數據x進行des加密,des-1
(kl[y])表示用密鑰k對數據y進行解密。
sessionkey的計算採用3des演算法,計算出單倍長度的密鑰。表示法為:sk
=
session(dk,data)
3des加密演算法為:
void
3des(byte
doublekeystr[16],
byte
data[8],
byte
out[8])
{
byte
buf1[8],
buf2[8];
des
(doublekeystr[0],
data,
buf1);
udes(doublekeystr[8],
buf1,
buf2);
des
(doublekeystr[0],
buf2,
out);
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/183957.html