des加密偏移量
A. 前端jsp登錄密碼加密為des3加密方法
*_*?我是誰
原創
關注
0點贊·757人閱讀
<%@ page contentType="text/html;charset=GBK"%>
<%@ page language="java" import="java.util.regex.*,
com.excellence.common.OAConstant,
com.excellence.common.UserInfo,
java.util.*,
java.text.SimpleDateFormat," %>
<html>
<head>
<title>XX系統</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link rel="stylesheet" href="/common/styles/default/default.css" type="text/css">
</head>
<script language="javascript">
</script>
<script language="JavaScript" src="/oa/javascripts/crypto-js.js"></script>
<body bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0">
<center>
</center>
</body>
<script type="text/vbscript">
Function str2asc(strstr)
str2asc = hex(asc(strstr))
End Function
Function asc2str(ascasc)
asc2str = chr(ascasc)
End Function
</script>
<script>
<%
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo ");
String account="";
//獲取用戶賬號
if(userInfo.getAccount()!=null&&!"".equals(userInfo.getAccount()))
account=userInfo.getAccount();
//有效期:格式:yyyy-MM-dd HH:mm:ss 有效期不能設置超過10分鍾
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
Date date = new Date(now .getTime() + 600000);
String time = df.format(date);
%>
//sessionid = base64(DES(用戶賬號&有效期))
//DES key:67HT4WrP
var sessionId = "<%=account%>" + "&" + "<%=time%>";
var mykey = "67HT4WrP";
// DES加密模式:CBC模式/ECB模式
// CBC模式加密
function encryptCBC(text, textKey) {
// 密鑰轉成16進制的字元串
var key = CryptoJS.enc.Utf8.parse(textKey);
// 加密過程
var encrypted = CryptoJS.DES.encrypt(text, key, {
// iv偏移量為key值
iv: key,
// 模式為CBC
mode: CryptoJS.mode.CBC,
// DES加密padding為Pkcs7
padding: CryptoJS.pad.Pkcs7
});
// 加密返回為字元串密文(加密經過一次base64加密,結果可看結果)
return encrypted.toString();
}
//對字元串中的特殊字元進行UrlEncode轉碼
function UrlEncode(str){
var ret="";
var strSpecial="!\"#$%&'()*+,/:;<=>?[]^`{|}~%";
var tt= "";
for(var i=0;i<str.length;i++){
var chr = str.charAt(i);
var c=str2asc(chr);
tt += chr+":"+c+"n";
if(parseInt("0x"+c) > 0x7f){
ret+="%"+c.slice(0,2)+"%"+c.slice(-2);
}else{
if(chr==" ")
ret+="+";
else if(strSpecial.indexOf(chr)!=-1)
ret+="%"+c.toString(16);
else
ret+=chr;
}
}
return ret;
}
//對sessionid進行加密
var desPass=encryptCBC(sessionId,mykey);
//對加密的sessionid中的特殊字元轉碼
var desPassEncode=UrlEncode(desPass);
//URL格式:http://xxxxxxxxxxxx?sessionid=&appid=&redirectUrl=~/Portals/Views/Test/index.html
var url="http://xxxxxxxxxxxx?sessionid="+desPassEncode+"&appid=&redirectUrl=~/Portals/Views/Test/index.html";
window.close();
window.open(url);
</script>
</html>
登錄後復制
注意事項:
1、crypto-js.js使用到了這個js,要記得引入,很多地方可以下載的,除了這裡面能用到des加密,也可以從網上找其他的des加密腳本,但是因為des加密模式的問題,要注意調用函數時參數的使用,確定自己要使用的是哪種des加密方法。
2、因為這里實現的是自動登錄,涉及到了url的處理,由於使用了加密,密文中會含有特殊字元,直接通過url轉跳,要把url中含有的特殊字元進行UrlEncode轉碼。
3、注意這里des的加密方式,這樣進行轉跳,跳進去的網站是.net實現的,因為des的加密模式有幾種,java,.net等默認的des加密模式有可能不一致,就會導致加密後的密文不一樣,所以要確定自己使用哪種模式,或者直接輸出加密密文來進行比較。
4、使用js比較方便的地方是因為我這里用的jsp頁面,所以對處理的數據可以任意寫,而且不會影響後台的使用,我覺得這是js的好處,特別是進行像這種進行類似單點登錄,自己系統用的java實現,而別人用的.net,直接用腳本,可以節省時間,不會對自己系統造成什麼影響。
5、有一個地方要注意,這里對url進行轉碼時,使用到了VB腳本的一些函數,這種腳本已經很少有人會用了,而且有些瀏覽器已經不支持了,網路顯示ie11不支持,但是我自己的電腦就是ie11,可以使用,所以這個也不是絕對的,有可能和使用到的函數有關。
6、除了des加密,還有md5,單獨的base64加密,這些常用的加密方式,都可以直接用js腳本實現。
7、這里只有des的一種加密模式,還有其他的,crypto-js.js中都有,可以網路下其他加密方法的使用!
B. C# DES加密後存儲,解密後顯示問題。
在我這里測試你的代碼是可以的,不過我把object o = sr.ReadLine();改成了object o = sr.ReadToEnd();
C. VS中用C#編寫一個DES(或3DES)加解密的Windows應用程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ZU14
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//ZU14.DES des = new ZU14.DES();
ZU14.DES des = null;
private void btn_jiami_Click(object sender, EventArgs e)
{
textBox2.Text = des.Encrypt(textBox1.Text);
// MessageBox.Show("加密成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
private void btn_jiemi_Click(object sender, EventArgs e)
{
textBox3.Text = des.Decrypt(textBox2.Text);
//MessageBox.Show("解密成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
private void btn_wjjiami_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = @"d:\";
open.Filter = "文本文件(*.txt,*.doc,*.xls)|*.txt;*.doc;*.xls";
if (open.ShowDialog()== DialogResult.OK)
{
des.EncryptFile(open.FileName, open.FileName);
MessageBox.Show("加密成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
private void btn_wjjiemi_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = @"d:\";
open.Filter = "文本文件(*.txt,*.doc,*.xls)|*.txt;*.doc;*.xls";
if (open.ShowDialog() == DialogResult.OK)
{
des.DecryptFile(open.FileName);
MessageBox.Show("解密成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
private void button1_Click(object sender, EventArgs e)
{
zifu.setmisi1 = textBox4.Text.Trim();
zifu.setmisi2 = textBox5.Text.Trim();
des = new ZU14.DES();
}
}
}
上面的代碼是窗體的
下面是調用的兩個類的
using System;
using System.Collections.Generic;
using System.Text;
namespace ZU14
{
class zifu
{
private static string misi1;
private static string misi2;
public static string getmisi1
{
get
{
return misi1;
}
}
public static string setmisi1
{
set
{
misi1 = value;
}
}
public static string getmisi2
{
get
{
return misi2;
}
}
public static string setmisi2
{
set
{
misi2 = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Collections;
using System.Data;
using System.Windows.Forms;
namespace ZU14
{
class DES
{
string iv =zifu.getmisi1; //"1234的yza";
string key = zifu.getmisi2;//"123在yzb";
/// <summary>
/// DES加密偏移量,必須是>=8位長的字元串
/// </summary>
public string IV
{
get { return iv; }
set { iv = value; }
}
/// <summary>
/// DES加密的私鑰,必須是8位長的字元串
/// </summary>
public string Key
{
get { return key; }
set { key = value; }
}
/// <summary>
/// 對字元串進行DES加密
/// </summary>
/// <param name="sourceString">待加密的字元串</param>
/// <returns>加密後的BASE64編碼的字元串</returns>
public string Encrypt(string sourceString)
{
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Encoding.Default.GetBytes(sourceString);
try
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Convert.ToBase64String(ms.ToArray());
}
catch
{
throw;
}
}
}
/// <summary>
/// 對DES加密後的字元串進行解密
/// </summary>
/// <param name="encryptedString">待解密的字元串</param>
/// <returns>解密後的字元串</returns>
public string Decrypt(string encryptedString)
{
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Convert.FromBase64String(encryptedString);
try
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Encoding.Default.GetString(ms.ToArray());
}
catch
{
throw;
}
}
}
/// <summary>
/// 對文件內容進行DES加密
/// </summary>
/// <param name="sourceFile">待加密的文件絕對路徑</param>
/// <param name="destFile">加密後的文件保存的絕對路徑</param>
public void EncryptFile(string sourceFile, string destFile)
{
if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路徑不存在!", sourceFile);
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] btFile = File.ReadAllBytes(sourceFile);
using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
{
try
{
using (CryptoStream cs = new CryptoStream(fs, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(btFile, 0, btFile.Length);
cs.FlushFinalBlock();
}
}
catch
{
// throw;
}
finally
{
fs.Close();
}
}
}
/// <summary>
/// 對文件內容進行DES加密,加密後覆蓋掉原來的文件
/// </summary>
/// <param name="sourceFile">待加密的文件的絕對路徑</param>
public void EncryptFile(string sourceFile)
{
EncryptFile(sourceFile, sourceFile);
}
/// <summary>
/// 對文件內容進行DES解密
/// </summary>
/// <param name="sourceFile">待解密的文件絕對路徑</param>
/// <param name="destFile">解密後的文件保存的絕對路徑</param>
public void DecryptFile(string sourceFile, string destFile)
{
if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路徑不存在!", sourceFile);
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] btFile = File.ReadAllBytes(sourceFile);
using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
{
try
{
using (CryptoStream cs = new CryptoStream(fs, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(btFile, 0, btFile.Length);
cs.FlushFinalBlock();
}
}
catch
{
// MessageBox.Show(ex.Message);
//throw;
}
finally
{
fs.Close();
}
}
}
/// <summary>
/// 對文件內容進行DES解密,加密後覆蓋掉原來的文件
/// </summary>
/// <param name="sourceFile">待解密的文件的絕對路徑</param>
public void DecryptFile(string sourceFile)
{
DecryptFile(sourceFile, sourceFile);
}
}
}
有什麼看不明白的,再聯系我,我的賬號就是我的QQ
D. C# DES加密解密問題
這個其實就是一個加密解密問題而已,演算法網上都有。
button1提交的時候加密內容後存入資料庫,button搜索的時候先加密用於搜索的字元然後查詢資料庫查出來再解密綁定到datagridview上就行了。
當然這里因為加密了所以你搜索的時候只能全詞搜索而不能做模糊匹配搜索。
/// <summary>
/// DEC 加密過程
/// </summary>
/// <param name="pToEncrypt">被加密的字元串</param>
/// <param name="sKey">密鑰(只支持8個位元組的密鑰)</param>
/// <returns>加密後的字元串</returns>
public string Encrypt(string pToEncrypt, string sKey)
{
//訪問數據加密標准(DES)演算法的加密服務提供程序 (CSP) 版本的包裝對象
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);//建立加密對象的密鑰和偏移量
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey); //原文使用ASCIIEncoding.ASCII方法的GetBytes方法
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);//把字元串放到byte數組中
MemoryStream ms = new MemoryStream();//創建其支持存儲區為內存的流
//定義將數據流鏈接到加密轉換的流
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//上面已經完成了把加密後的結果放到內存中去
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
/// <summary>
/// DEC 解密過程
/// </summary>
/// <param name="pToDecrypt">被解密的字元串</param>
/// <param name="sKey">密鑰(只支持8個位元組的密鑰,同前面的加密密鑰相同)</param>
/// <returns>返回被解密的字元串</returns>
public string Decrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for (int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);//建立加密對象的密鑰和偏移量,此值重要,不能修改
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//建立StringBuild對象,createDecrypt使用的是流對象,必須把解密後的文本變成流對象
StringBuilder ret = new StringBuilder();
return System.Text.Encoding.Default.GetString(ms.ToArray());
}
E. 求一簡單的 DES加密實例。要c#.net實現!
public sealed class DES
{
private static string iv = "123456789";
private static string key = "12345678"; /// <summary>
/// DES加密偏移量,必須是>=8位長的字元串
/// </summary>
public string IV
{
get { return iv; }
set { iv = value; }
} /// <summary>
/// DES加密的私鑰,必須是8位長的字元串
/// </summary>
///
public string Key
{
get { return key; }
set { key = value; }
} /// <summary>
/// 對字元串進行DES加密
/// </summary>
/// <param name="sourceString">待加密的字元串</param>
/// <returns>加密後的BASE64編碼的字元串</returns> public static string Encrypt(string sourceString)
{
if (sourceString != "")
{
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Encoding.Default.GetBytes(sourceString);
try
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Convert.ToBase64String(ms.ToArray());
}
catch
{
throw;
}
}
}
else
return "";
} /// <summary>
/// 對DES加密後的字元串進行解密
/// </summary>
/// <param name="encryptedString">待解密的字元串</param>
/// <returns>解密後的字元串</returns> public static string Decrypt(string encryptedString)
{
if (encryptedString != "")
{
byte[] btKey = Encoding.Default.GetBytes(key);
byte[] btIV = Encoding.Default.GetBytes(iv);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Convert.FromBase64String(encryptedString);
try
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Encoding.Default.GetString(ms.ToArray());
}
catch
{
throw;
}
}
}
else
return "";
}}
F. DES 加密演算法解析
第一步是用密鑰初始化des
初始化的過程主要是用傳入的密鑰生成16對長度為48的Kn 子密鑰
生成48位子密鑰Kn的函數主要是 __create_sub_keys , 主要設計兩個換位表pc1和pc2
key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey())) 開始先用換位表生成56位的初始key值(同pc1表的位數)
之後劃分成兩部分self.L和self.R各28位,然後是一個循環16此的左移操作,最後用pc2換位表生成第一個子密鑰Kn[0]
我們傳入數據調用encrypt函數即可, DES.encrypt('flag{isisisikey}') 我們先來看encrypt函數
encrypt函數主要調用了crypt函數,繼續跟進crypt函數,開始一部分是cbc模式獲取iv的過程,這里先暫時不考慮cbc,直接看關鍵部分
這里就設計到分組加密的核心了,為什麼DES又叫分組加密,有一操作是 block = self.__String_to_BitList(data[i:i+8]) 把加密數據每八個位元組分成一個block,然後調用 __String_to_BitList 會將八位元組字元轉換為64bit的二進制,每個block再調用 __des_crypt 函數加密
開始幾步和子密鑰生成函數類似,用一個ip換位表初始化block,然後劃分成self,L和self.R 各32位。
之後又是一個16輪的計算,我們分析一下每輪操作
self.R = self.__permutate(des.__expansion_table, self.R) 利用一個擴展表將32bit擴展成48位,擴展表:
B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] 將48位的self.R 分成6*8為,之後一個循環就是經典的是s-box的置換操作
s-box盒一個八個,m是前後2bit,n是中間6bit, v是s-box的(n,m)處的值
self.R = self.__permutate(des.__p, Bn) 是P-box置換盒。 最後返回64bit的processed_block, 經過BitList_to_String函數處理就變成8位元組的字元流了,最後把每個block分組join一塊就是最後的密文。
我們再來總結一下這個過程
子密鑰生成演算法
des 加密演算法
附上完整版des加解密演算法腳本
G. DES加密解密問題,java 和 C#
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.IO;
usingSystem.Security;
usingSystem.Security.Cryptography;
/*----------------------------------------------
*DES加密、解密類庫,字元串加密結果使用BASE64編碼返回,支持文件的加密和解密
*作者:三角貓/DeltaCat
*網址:
*轉載務必保留此信息
*---------------------------------------------
*/
namespaceZU14
{
publicsealedclassDES
{
stringiv="1234的yzo";
stringkey="123在yzo";
///<summary>
///DES加密偏移量,必須是>=8位長的字元串
///</summary>
publicstringIV
{
get{returniv;}
set{iv=value;}
}
///<summary>
///DES加密的私鑰,必須是8位長的字元串
///</summary>
publicstringKey
{
get{returnkey;}
set{key=value;}
}
///<summary>
///對字元串進行DES加密
///</summary>
///<paramname="sourceString">待加密的字元串</param>
///<returns>加密後的BASE64編碼的字元串</returns>
publicstringEncrypt(stringsourceString)
{
byte[]btKey=Encoding.Default.GetBytes(key);
byte[]btIV=Encoding.Default.GetBytes(iv);
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
using(MemoryStreamms=newMemoryStream())
{
byte[]inData=Encoding.Default.GetBytes(sourceString);
try
{
using(CryptoStreamcs=newCryptoStream(ms,des.CreateEncryptor(btKey,btIV),CryptoStreamMode.Write))
{
cs.Write(inData,0,inData.Length);
cs.FlushFinalBlock();
}
returnConvert.ToBase64String(ms.ToArray());
}
catch
{
throw;
}
}
}
///<summary>
///對DES加密後的字元串進行解密
///</summary>
///<paramname="encryptedString">待解密的字元串</param>
///<returns>解密後的字元串</returns>
publicstringDecrypt(stringencryptedString)
{
byte[]btKey=Encoding.Default.GetBytes(key);
byte[]btIV=Encoding.Default.GetBytes(iv);
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
using(MemoryStreamms=newMemoryStream())
{
byte[]inData=Convert.FromBase64String(encryptedString);
try
{
using(CryptoStreamcs=newCryptoStream(ms,des.CreateDecryptor(btKey,btIV),CryptoStreamMode.Write))
{
cs.Write(inData,0,inData.Length);
cs.FlushFinalBlock();
}
returnEncoding.Default.GetString(ms.ToArray());
}
catch
{
throw;
}
}
}
///<summary>
///對文件內容進行DES加密
///</summary>
///<paramname="sourceFile">待加密的文件絕對路徑</param>
///<paramname="destFile">加密後的文件保存的絕對路徑</param>
publicvoidEncryptFile(stringsourceFile,stringdestFile)
{
if(!File.Exists(sourceFile))thrownewFileNotFoundException("指定的文件路徑不存在!",sourceFile);
byte[]btKey=Encoding.Default.GetBytes(key);
byte[]btIV=Encoding.Default.GetBytes(iv);
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
byte[]btFile=File.ReadAllBytes(sourceFile);
using(FileStreamfs=newFileStream(destFile,FileMode.Create,FileAccess.Write))
{
try
{
using(CryptoStreamcs=newCryptoStream(fs,des.CreateEncryptor(btKey,btIV),CryptoStreamMode.Write))
{
cs.Write(btFile,0,btFile.Length);
cs.FlushFinalBlock();
}
}
catch
{
throw;
}
finally
{
fs.Close();
}
}
}
///<summary>
///對文件內容進行DES加密,加密後覆蓋掉原來的文件
///</summary>
///<paramname="sourceFile">待加密的文件的絕對路徑</param>
publicvoidEncryptFile(stringsourceFile)
{
EncryptFile(sourceFile,sourceFile);
}
///<summary>
///對文件內容進行DES解密
///</summary>
///<paramname="sourceFile">待解密的文件絕對路徑</param>
///<paramname="destFile">解密後的文件保存的絕對路徑</param>
publicvoidDecryptFile(stringsourceFile,stringdestFile)
{
if(!File.Exists(sourceFile))thrownewFileNotFoundException("指定的文件路徑不存在!",sourceFile);
byte[]btKey=Encoding.Default.GetBytes(key);
byte[]btIV=Encoding.Default.GetBytes(iv);
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
byte[]btFile=File.ReadAllBytes(sourceFile);
using(FileStreamfs=newFileStream(destFile,FileMode.Create,FileAccess.Write))
{
try
{
using(CryptoStreamcs=newCryptoStream(fs,des.CreateDecryptor(btKey,btIV),CryptoStreamMode.Write))
{
cs.Write(btFile,0,btFile.Length);
cs.FlushFinalBlock();
}
}
catch
{
throw;
}
finally
{
fs.Close();
}
}
}
///<summary>
///對文件內容進行DES解密,加密後覆蓋掉原來的文件
///</summary>
///<paramname="sourceFile">待解密的文件的絕對路徑</param>
publicvoidDecryptFile(stringsourceFile)
{
DecryptFile(sourceFile,sourceFile);
}
}
}
H. 使用.net內置的DES進行加密
好了,明白了它的License種類,我們得看看它是如何驗證合法的License的,換句話說就是它的License是如何構成的。它通過定位/bin目錄下的License文件,License文件由類名(FreeTextBox)+ 「.lic」構成。FreeTextBox.Lic文件內容分三個部分,第一部分為明文FreeTextBox License,也就是類名+ License」字元串,第二部分為[License種類的加密文本],加密演算法採用的.NET內置的DES,用於DES加密的密鑰和偏移量均為{ 0x39, 0x48, 0x42, 50, 0x38, 0x31, 70, 0x36 },當然它不是直接對文本加密的,做了一個小小的處理,這個處理就是加上原文本的長度,並預留5位,不夠則補零,例如字元串DistributionLicense,那用於加密的就是00019DistributionLicense,因為字元串DistributionLicense的長度是19位,前面還有3個空位就補3個零。這樣加密後的結果就是=,注意需要用[]分隔,FreeTextBox設計者出於方便使用正則匹配所以使用[]來分隔,第三部分就是你注冊標識的加密文本,當然也有[],處理方式跟第二部分的一樣,例如我的域名為Ycweb.Net,我想以此作為標識來生成License,於是對字元串00009Ycweb.Net進行DES加密,結果為tyn3Gf1Y5GH2VphAJ2U++g==,所以綜合這個三個部分的內容,就構成了一個完整的License文件內容,整理一下就是: FreeTextBox License [=] [tyn3Gf1Y5GH2VphAJ2U++g==] 這是Distribution的License,如果是Professional的License,內容就是: FreeTextBox License [tyn3Gf1Y5GH2VphAJ2U++g==] 補充: 我現在是要加密的方法,求一個函數,將原文:00019DistributionLicense,加密為密文:=],不知所謂,連內容都不看就回答了 補充: 又多一個不看內容的,文章裡面不是說了嗎:
I. 對稱加密演算法之DES介紹
DES (Data Encryption Standard)是分組對稱密碼演算法。
DES演算法利用 多次組合替代演算法 和 換位演算法 ,分散和錯亂的相互作用,把明文編製成密碼強度很高的密文,它的加密和解密用的是同一演算法。
DES演算法,是一種 乘積密碼 ,其在演算法結構上主要採用了 置換 、 代替 、 模二相加 等函數,通過 輪函數 迭代的方式來進行計算和工作。
DES演算法也會使用到數據置換技術,主要有初始置換 IP 和逆初始置換 IP^-1 兩種類型。DES演算法使用置換運算的目的是將原始明文的所有格式及所有數據全部打亂重排。而在輪加密函數中,即將數據全部打亂重排,同時在數據格式方面,將原有的32位數據格式,擴展成為48位數據格式,目的是為了滿足S盒組對數據長度和數據格式規范的要求。
一組數據信息經過一系列的非線性變換以後,很難從中推導出其計算的過程和使用的非線性組合;但是如果這組數據信息使用的是線性變換,計算就容易的多。在DES演算法中,屬於非線性變換的計算過程只有S盒,其餘的數據計算和變換都是屬於線性變換,所以DES演算法安全的關鍵在於S盒的安全強度。此外,S盒和置換IP相互配合,形成了很強的抗差分攻擊和抗線性攻擊能力,其中抗差分攻擊能力更強一些。
DES演算法是一種分組加密機制,將明文分成N個組,然後對各個組進行加密,形成各自的密文,最後把所有的分組密文進行合並,形成最終的密文。
DES加密是對每個分組進行加密,所以輸入的參數為分組明文和密鑰,明文分組需要置換和迭代,密鑰也需要置換和循環移位。在初始置換IP中,根據一張8*8的置換表,將64位的明文打亂、打雜,從而提高加密的強度;再經過16次的迭代運算,在這些迭代運算中,要運用到子密鑰;每組形成的初始密文,再次經過初始逆置換 IP^-1 ,它是初始置換的逆運算,最後得到分組的最終密文。
圖2右半部分,給出了作用56比特密鑰的過程。DES演算法的加密密鑰是64比特,但是由於密鑰的第n*8(n=1,2…8)是校驗(保證含有奇數個1),因此實際參與加密的的密鑰只有 56比特 。開始時,密鑰經過一個置換,然後經過循環左移和另一個置換分別得到子密鑰ki,供每一輪的迭代加密使用。每輪的置換函數都一樣,但是由於密鑰位的重復迭代使得子密鑰互不相同。
DES演算法 利用多次組合替代演算法和換位演算法,分散和錯亂的相互作用,把明文編製成密碼強度很高的密文,它的加密和解密用的是同一演算法。
DES演算法詳述:DES對64位明文分組(密鑰56bit)進行操作。
1、 初始置換函數IP:64位明文分組x經過一個初始置換函數IP,產生64位的輸出x0,再將分組x0分成左半部分L0和右半部分R0:即將輸入的第58位換到第一位,第50位換到第2位,…,依次類推,最後一位是原來的第7位。L0、R0則是換位輸出後的兩部分,L0是輸出的左32位,R0是右32位。例,設置換前的輸入值為D1D2D3…D64,則經過初始置換後的結果為:L0=D58D50…D8;R0=D57D49…D7.其置換規則如表1所示。
DES加密過程最後的逆置換 IP^-1 ,是表1的 逆過程 。就是把原來的每一位都恢復過去,即把第1位的數據,放回到第58位,把第2位的數據,放回到第50位。
2、 獲取子密鑰 Ki :DES加密演算法的密鑰長度為56位,一般表示為64位(每個第8位用於奇偶校驗),將用戶提供的64位初始密鑰經過一系列的處理得到K1,K2,…,K16,分別作為 1~16 輪運算的 16個子密鑰 。
(1). 將64位密鑰去掉8個校驗位,用密鑰置換 PC-1 (表2)置換剩下的56位密鑰;
(2). 將56位分成前28位C0和後28位D0,即 PC-1(K56)=C0D0 ;
(3). 根據輪數,這兩部分分別循環左移1位或2位,表3:
(4). 移動後,將兩部分合並成56位後通過壓縮置換PC-2(表4)後得到48位子密鑰,即Ki=PC-2(CiDi).
子密鑰產生如圖2所示:
3、 密碼函數F(非線性的)
(1). 函數F的操作步驟:密碼函數F 的輸入是32比特數據和48比特的子密鑰:
A.擴展置換(E):將數據的右半部分Ri從32位擴展為48位。位選擇函數(也稱E盒),如表5所示:
B.異或:擴展後的48位輸出E(Ri)與壓縮後的48位密鑰Ki作異或運算;
C.S盒替代:將異或得到的48位結果分成八個6位的塊,每一塊通過對應的一個S盒產生一個4位的輸出。
(2)、D、P盒置換:將八個S盒的輸出連在一起生成一個32位的輸出,輸出結果再通過置換P產生一個32位的輸出即:F(Ri,Ki),F(Ri,Ki)演算法描述如圖3,最後,將P盒置換的結果與最初的64位分組的左半部分異或,然後,左、右半部分交換,開始下一輪計算。
4、密文輸出:經過16次迭代運算後,得到L16、R16,將此作為輸入,進行逆置換,即得到密文輸出。逆置換正好是初始置的逆運算。例如,第1位經過初始置換後,處於第40位,而通過逆置換,又將第40位換回到第1位,其逆置換規則如表8所示:
圖4為DES演算法加密原理圖:
DES演算法加密和解密過程採用相同的演算法,並採用相同的加密密鑰和解密密鑰,兩者的區別是:(1)、DES加密是從L0、R0到L15、R15進行變換,而解密時是從L15、R15到L0、R0進行變換的;(2)、加密時各輪的加密密鑰為K0K1…K15,而解密時各輪的解密密鑰為K15K14…K0;(3)、加密時密鑰循環左移,解密時密鑰循環右移。
DES加密過程分析:
(1)、首先要生成64位密鑰,這64位的密鑰經過「子密鑰演算法」換轉後,將得到總共16個子密鑰。將這些子密鑰標識為Kn(n=1,2,…,16)。這些子密鑰主要用於總共十六次的加密迭代過程中的加密工具。
(2)、其次要將明文信息按64位數據格式為一組,對所有明文信息進行分組處理。每一段的64位明文都要經過初試置換IP,置換的目的是將數據信息全部打亂重排。然後將打亂的數據分為左右兩塊,左邊一塊共32位為一組,標識為L0;右邊一塊也是32位為一組,標識為R0.
(3)、置換後的數據塊總共要進行總共十六次的加密迭代過程。加密迭代主要由加密函數f來實現。首先使用子密鑰K1對右邊32位的R0進行加密處理,得到的結果也是32位的;然後再將這個32位的結果數據與左邊32位的L0進行模2處理,從而再次得到一個32位的數據組。我們將最終得到的這個32位組數據,作為第二次加密迭代的L1,往後的每一次迭代過程都與上述過程相同。
(4)、在結束了最後一輪加密迭代之後,會產生一個64位的數據信息組,然後我們將這個64位數據信息組按原有的數據排列順序平均分為左右兩等分,然後將左右兩等分的部分進行位置調換,即原來左等分的數據整體位移至右側,而原來右等分的數據則整體位移至左側,這樣經過合並後的數據將再次經過逆初始置換IP^-1的計算,我們最終將得到一組64位的密文。
DES解密過程分析:DES的解密過程與它的加密過程是一樣的,這是由於DES演算法本身屬於對稱密碼體制演算法,其加密和解密的過程可以共用同一個過程和運算。
DES加密函數f:在DES演算法中,要將64位的明文順利加密輸出成64位的密文,而完成這項任務的核心部分就是加密函數f。加密函數f的主要作用是在第m次的加密迭代中使用子密鑰Km對Km-1進行加密操作。加密函數f在加密過程中總共需要運行16輪。
十六輪迭代演算法:它先將經過置換後的明文分成兩組,每組32位;同時密鑰也被分成了兩組,每組28位,兩組密鑰經過運算,再聯合成一個48位的密鑰,參與到明文加密的運算當中。S盒子,它由8個4*16的矩陣構成,每一行放著0到15的數據,順序各個不同,是由IBM公司設計好的。經過異或運算的明文,是一個48位的數據,在送入到S盒子的時候,被分成了8份,每份6位,每一份經過一個S盒子,經過運算後輸出為4位,即是一個0到15的數字的二進製表示形式。具體運算過程為,將輸入的6位中的第1位為第6位合並成一個二進制數,表示行號,其餘4位也合並成一個二進制數,表示列號。在當前S盒子中,以這個行號和列號為准,取出相應的數,並以二進制的形式表示,輸出,即得到4位的輸出,8個S盒子共計32位。
DES演算法優缺點:
(1)、產生密鑰簡單,但密鑰必須高度保密,因而難以做到一次一密;
(2)、DES的安全性依賴於密鑰的保密。攻擊破解DES演算法的一個主要方法是通過密鑰搜索,使用運算速度非常高的計算機通過排列組合枚舉的方式不斷嘗試各種可能的密鑰,直到破解為止。一般,DES演算法使用56位長的密鑰,通過簡單計算可知所有可能的密鑰數量最多是2^56個。隨著巨型計算機運算速度的不斷提高,DES演算法的安全性也將隨之下降,然而在一般的民用商業場合,DES的安全性仍是足夠可信賴的。
(3)、DES演算法加密解密速度比較快,密鑰比較短,加密效率很高但通信雙方都要保持密鑰的秘密性,為了安全還需要經常更換DES密鑰。
參考鏈接 : https://blog.csdn.net/fengbingchun/article/details/42273257
J. 如何用php實現和c#一致的DES加密解密
PHP實現和c#一致的DES加密解密,可以從網上搜到一大堆,但是測試後發現都沒法用。以下正確代碼是我經過苦苦才找到的。希望大家在系統整合時能用的上。
注意:key的長度為8位以內。
[csharp]viewplainprint?
//C#版DES加解密演算法
usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
usingSystem.Data.SqlClient;
usingSystem.Security.Cryptography;
usingSystem.IO;
usingSystem.Text;
publicclassDes{
//加解密密鑰
privatestaticstringskey="12345678";
//初始化向量
privatestaticbyte[]DESIV={0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF};
#regionDESEnCodeDES加密
publicstaticstringDESEnCode(stringpToEncrypt,stringsKey)
{
pToEncrypt=HttpContext.Current.Server.UrlEncode(pToEncrypt);
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
byte[]inputByteArray=Encoding.GetEncoding("UTF-8").GetBytes(pToEncrypt);
//建立加密對象的密鑰和偏移量
//原文使用ASCIIEncoding.ASCII方法的GetBytes方法
//使得輸入密碼必須輸入英文文本
des.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStreamms=newMemoryStream();
CryptoStreamcs=newCryptoStream(ms,des.CreateEncryptor(),CryptoStreamMode.Write);
cs.Write(inputByteArray,0,inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilderret=newStringBuilder();
foreach(bytebinms.ToArray())
{
ret.AppendFormat("{0:X2}",b);
}
ret.ToString();
returnret.ToString();
}
#endregion
///<summary>
///
///</summary>
///<paramname="pToDecrypt">待解密的字元串</param>
///<paramname="sKey">解密密鑰,要求為8位元組,和加密密鑰相同</param>
///<returns>解密成功返回解密後的字元串,失敗返源串</returns>
#regionDESDeCodeDES解密
publicstaticstringDESDeCode(stringpToDecrypt,stringsKey)
{
//HttpContext.Current.Response.Write(pToDecrypt+"<br>"+sKey);
//HttpContext.Current.Response.End();
DESCryptoServiceProviderdes=newDESCryptoServiceProvider();
byte[]inputByteArray=newbyte[pToDecrypt.Length/2];
for(intx=0;x<pToDecrypt.Length/2;x++)
{
inti=(Convert.ToInt32(pToDecrypt.Substring(x*2,2),16));
inputByteArray[x]=(byte)i;
}
des.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStreamms=newMemoryStream();
CryptoStreamcs=newCryptoStream(ms,des.CreateDecryptor(),CryptoStreamMode.Write);
cs.Write(inputByteArray,0,inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilderret=newStringBuilder();
returnHttpContext.Current.Server.UrlDecode(System.Text.Encoding.Default.GetString(ms.ToArray()));
}
#endregion
}
[php]viewplainprint?
<?php
classDES
{
var$key;
var$iv;//偏移量
functionDES($key,$iv=0){
//key長度8例如:1234abcd
$this->key=$key;
if($iv==0){
$this->iv=$key;//默認以$key作為iv
}else{
$this->iv=$iv;//mcrypt_create_iv(mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC),MCRYPT_DEV_RANDOM);
}
}
functionencrypt($str){
//加密,返回大寫十六進制字元串
$size=mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC);
$str=$this->pkcs5Pad($str,$size);
returnstrtoupper(bin2hex(mcrypt_cbc(MCRYPT_DES,$this->key,$str,MCRYPT_ENCRYPT,$this->iv)));
}
functiondecrypt($str){
//解密
$strBin=$this->hex2bin(strtolower($str));
$str=mcrypt_cbc(MCRYPT_DES,$this->key,$strBin,MCRYPT_DECRYPT,$this->iv);
$str=$this->pkcs5Unpad($str);
return$str;
}
functionhex2bin($hexData){
$binData="";
for($i=0;$i<strlen($hexData);$i+=2){
$binData.=chr(hexdec(substr($hexData,$i,2)));
}
return$binData;
}
functionpkcs5Pad($text,$blocksize){
$pad=$blocksize-(strlen($text)%$blocksize);
return$text.str_repeat(chr($pad),$pad);
}
functionpkcs5Unpad($text){
$pad=ord($text{strlen($text)-1});
if($pad>strlen($text))
returnfalse;
if(strspn($text,chr($pad),strlen($text)-$pad)!=$pad)
returnfalse;
returnsubstr($text,0,-1*$pad);
}
}
?>