DES算法的实现人民银行济南分行清算中心(250001) 张立锋 李宝成  
01-5-9 上午 09:49:17--------------------------------------------------------------------------------
 随着信息技术的发展,计算机应用渗透到社会生活的各个领域,特别是在电子商务中的应用,使人们对信息的依赖程度越来越大,从而使信息安全技术显得格外重要。信息安全技术主要是研究计算机系统信息的机密性、完整性、可获取性和真实性,它的核心是加密技术。加密技术根据加密密钥与解密密钥是否相同可分为对称加密技术(单密钥加密技术)和非对称加密技术(公开密钥加密技术)。  
DES(Data Encryption Standard)加密技术是一种常用的对称加密技术,该技术算法公开,加密强度大,运算速度快,在各行业甚至军事领域得到广泛的应用。DES算法从公布到现在已有20多年的历史,虽然有些人对它的加密强度持怀疑态度,但现在还没有发现实用的破译DES的方法。并且在应用中,人们不断提出新的方法增强DES算法的加密强度,如3重DES算法、带有交换S盒的DES算法等。本文介绍如何用VB实现DES算法。 
  
加解密原理 
DES运算的原始数据(加密前数据)和加密密钥都是64位的,将原始数据经过初始的置换,然后与子密钥(由加密密钥产生)经过一系列迭代运算,最后再经过逆置换,即可得到加密数据。解密过程与此类似。 
DES的加密密钥本身是64位,但其第8、16、24、32、40、48、56和64位是奇偶校验位,所以加密密钥实质上只有56位。子密钥K1(48位)是将这56位的数据经过选择换位,把产生结果分成左右两部分(L0和R0),将这两部分分别经过循环左移位,并将产生的结果再合并,最后将合并后数据经过缩小换位得到的。子密钥K2、K3……K16的产生过程与此类似。 
公式表示如下: 
L[0]R[0] = SelectChangeEKIP (加密密钥) 
L[i] = ShiftString (L[i-1]) 
R[i] = ShiftString (R[i-1]) 
K[i] = SelectLittleEK (C[i]D[i]) 
 
密钥的实现 
’用来保存产生子密钥Ki时的循环移位次数 
Dim KiShiftNumber(1 To 16) As Integer  
’初始化产生子密钥Ki 需做的循环移位次数 
Sub InitShitNumber()  
KiShiftNumber(1) = 1 
For iLoop = 2 To 16 
If iLoop = 2 Or iLoop = 9 Or iLoop = 16 Then 
KiShiftNumber(iLoop) = KiShiftNumber(iLoop - 1) + 1 
Else 
KiShiftNumber(iLoop) = KiShiftNumber(iLoop - 1) + 2 
End If 
Next iLoop 
End Sub 
’实现二进制字符串的循环左移 
Function ShiftString(intShiftNumber As Integer,strInString As String) As String 
iTemp = Len(strInString) 
ReDim strTemp(1 To iTemp) 
strTemp1 = strInString 
For iLoop1 = 1 To intShiftNumber 
For iLoop = 1 To iTemp - 1 
strTemp(iLoop) = Mid(strTemp1,1+iLoop,1) 
Next iLoop 
strTemp(iTemp) = Left(strTemp1, 1) 
strTemp1 = “” 
For iLoop = 1 To iTemp 
strTemp1 = strTemp1 & strTemp(iLoop) 
Next iLoop 
Next iLoop1 
ShiftString = strTemp1 
End Function 
’实现加密密钥的选择换位 
Function SelectChangeEKIP(strInString As String) AsString  
’将十六进制字符串转化为二进制字符串 
strTemp1 = strChangToBinary(strInString)  
For iLoop = 1 To 64 
sTemp(iLoop) = Mid(strTemp1, iLoop, 1) 
Next iLoop 
SelectChangeEKIP = sTemp(57) & sTemp(49) & sTemp(41) & sTemp(33) & sTemp(25) & sTemp(17) & sTemp(9) & sTemp(1) & sTemp(58) & sTemp(50) & sTemp(42) & sTemp(34) & sTemp(26) & sTemp(18) & sTemp(10) & sTemp(2) & sTemp(59) & sTemp(51) & sTemp(43) & sTemp(35) & sTemp(27) & sTemp(19) & sTemp(11) & sTemp(3) & sTemp(60) & sTemp(52) & sTemp(44) & sTemp(36) & sTemp(63) & sTemp(55) & sTemp(47) & sTemp(39) & sTemp(31) & sTemp(23) & sTemp(15) & sTemp(7) & sTemp(62) & sTemp(54) & sTemp(46) & sTemp(38) & sTemp(30) & sTemp(22) & sTemp(14) & sTemp(6) & sTemp(61) & sTemp(53) & sTemp(45) & sTemp(37) & sTemp(29) & sTemp(21) & sTemp(13) & sTemp(5) & sTemp(28) & sTemp(20) & sTemp(12) & sTemp(4) 
End Function 
’实现加密密钥的缩小换位 
Function SelectLittleEK(strInString As String) As String  
For iLoop = 1 To 56 
sTemp(iLoop) = Mid(strInString, iLoop, 1) 
Next iLoop 
SelectLittleEK = sTemp(14) & sTemp(17) & sTemp(11) & sTemp(24) & sTemp(1) & sTemp(5) & sTemp(3) & sTemp(28) & sTemp(15) & sTemp(6) & sTemp(21) & sTemp(10) & sTemp(23) & sTemp(19) & sTemp(12) & sTemp(4) & sTemp(26) & sTemp(8) & sTemp(16) & sTemp(7) & sTemp(27) & sTemp(20) & sTemp(13) & sTemp(2) & sTemp(41) & sTemp(52) & sTemp(31) & sTemp(37) & sTemp(47) & sTemp(55) & sTemp(30) & sTemp(40) & sTemp(51) & sTemp(45) & sTemp(33) & sTemp(48) & sTemp(44) & sTemp(49) & sTemp(39) & sTemp(56) & sTemp(34) & sTemp(53) & sTemp(46) & sTemp(42) & sTemp(50) & sTemp(36) & sTemp(29) & sTemp(32) 
End Function 
’产生子密钥Ki 
Function GetEncK(iNumber As Integer, strInString As String) As String  
’初始化产生子密钥Ki 需做的循环移位次数 
InitShitNumber 
’加密密钥的选择换位 
strTemp = SelectChangeEKIP(strInString)  
’左半部分循环左移 
strLeft = ShiftString(KiShiftNumber(iNumber), Left(strTemp, 28))  
’右半部分循环左移 
strRight = ShiftString(KiShiftNumber(iNumber), Right(strTemp, 28))  
’实现缩小换位得到子密钥Ki 
GetEncK = SelectLittleEK(strLeft & strRight)  
End Function 
 
加密原始数据 
首先把原始数据选择换位,将产生的数据分成左右两部分(L0和R0),每一部分各32位。然后将R0经过放大换位由32位变为48位,再与子密钥K1按位做异或运算,把产生结果通过选择函数变换为32位的数据,再经过单纯换位函数换位,换位后数据与L0做异或运算产生结果作为R1。最后把原来的R0作为L1,如此迭代16次,将R16和L16合并后的结果逆置换即可得到加密数据。 
公式表示如下: 
L[0]R[0] = SelectChangeDataIP(原始数据) 
L[i] = R[i-1] 
R[i] = L[i-1] xor f (R[i-1] , k[i]) 1<= i <= 16 
加密数据= InverseChangeData(R[16]L[16]) 
解密算法与此类似,只是在第一次迭代时使用的子密钥是K16,第二次是K15,最后一次是K1。 
此部分的详细代码请参见计算机世界网http://www.ccw.com.cn/app/aprog/01-5-7-4.asp。