iT邦幫忙

2

des 解密 vb python

小弟我在參考別的大大使用vb 編寫的解密程式
內容如下 :
`
Imports System
Imports System.Security.Cryptography
Imports System.Text

Module Program
Sub Main(args As String())
Dim FileNum As Integer
Dim strTemp As String

    Dim Key As String = "1158CB77"
    Dim hexString As String = "A755DDB424D77F7FBBDFC6B457587092"

    Dim des As New DESCryptoServiceProvider()
    'DESCryptoServiceProvider des = New DESCryptoServiceProvider()
    des.Mode = CipherMode.ECB
    des.IV = Encoding.ASCII.GetBytes(Key)
    des.Padding = PaddingMode.None
    des.Key = Encoding.ASCII.GetBytes(Key)

    Dim y = 2
    Dim s(hexString.Length / 2) As Byte
    Dim j = 0
    'Console.WriteLine(Len(hexString) / 2)
    For i As Integer = 0 To (Len(hexString) / 2 - 1)
        s(i) = Byte.Parse(Mid(hexString, j + 1, 1).ToString() + Mid(hexString, j + 2, 1).ToString(), System.Globalization.NumberStyles.HexNumber)
        'Console.WriteLine(s(i))
        j += 2
    Next
    Dim desencrypt As ICryptoTransform = des.CreateDecryptor()
    Dim h() As Byte = {s(0), s(1), s(2), s(3), s(4), s(5), s(6), s(7), s(8), s(9), s(10), s(11), s(12), s(13), s(14), s(15)}
    '                 {167 ,85   ,221  ,180  ,36   ,215   ,127  ,127  ,187  ,223  ,198  ,180   ,87    ,88    ,112   ,146}
    Dim re As String = Encoding.ASCII.GetString(desencrypt.TransformFinalBlock(h, 0, h.Length))
    Console.WriteLine(re) '1114420095

End Sub

End Module
`

想請教一下最後面的TransformFinalBlock,是怎麼把{167,85,221,180,36,215,127,127,187,223,198,180,87,88,112,146}
變成1114420095的。
小弟我嘗試使用python去翻譯,但都弄不出一個所以然
程式碼如下 :

#!/usr/bin/python
# -*- coding: utf-8 -*-
import binascii
from pyDes import des, CBC, PAD_PKCS5, ECB


def des_encrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, ECB, iv, pad=None, padmode=None)
    #print(k)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    #print(en)
    return binascii.b2a_hex(en)


def des_decrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, ECB, iv, pad=None, padmode=None)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de


secret_str = des_encrypt('1158CB77', '1114420095')
print ('密文:', secret_str)#b'a755ddb424d77f7f6e52fb9e82cc897f'
clear_str = des_decrypt('1158CB77', secret_str)
print ('明文:', clear_str)#b'1114420095'

test='A755DDB424D77F7FBBDFC6B457587092'
clear_str = des_decrypt('1158CB77', test)
print ('test:', clear_str) #None

請前輩們指教一下...

3
最佳解答

VB 那邊的加密應該是採用 pad 補零的方式

PY 這邊可以把 padmode 改為 PAD_NORMAL,並設定 pad 填補字元為 '\0'

這樣結果就和 VB 程式一樣了

def des_decrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, ECB, iv, pad='\0', padmode=PAD_NORMAL)
    de = k.decrypt(binascii.a2b_hex(s))
    return de
    
test='A755DDB424D77F7FBBDFC6B457587092'
clear_str = des_decrypt('1158CB77', test)
print ('test:', clear_str) # test: b'1114420095'

加密結果也是

def des_encrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, ECB, iv, pad='\0', padmode=PAD_NORMAL)
    en = k.encrypt(s)
    return binascii.b2a_hex(en)
    
secret_str = des_encrypt('1158CB77', '1114420095')
print ('密文:', secret_str) #b'a755ddb424d77f7fbbdfc6b457587092'
clear_str = des_decrypt('1158CB77', secret_str)
print ('明文:', clear_str) #b'1114420095'

現在想想其實有跡可循 ((馬後炮 /images/emoticon/emoticon16.gif

在測試的過程中,我試過把 padmode 改成 None
結果為 b'1114420095\x00\x00\x00\x00\x00\x00'
由此可以推測 hexString A755DDB424D77F7FBBDFC6B457587092
加密前應該有經過補零的動作
所以解回來才會多了一些零

def des_decrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, ECB, iv, pad=None, padmode=None)
    de = k.decrypt(binascii.a2b_hex(s))
    return de
    
test='A755DDB424D77F7FBBDFC6B457587092'
clear_str = des_decrypt('1158CB77', test)
print ('test:', clear_str) # test: b'1114420095\x00\x00\x00\x00\x00\x00'
看更多先前的回應...收起先前的回應...
froce iT邦大師 1 級 ‧ 2020-08-10 12:05:17 檢舉

嗯...或許乾脆寫隻程式把VB的轉成python的密文會更快。XD

另外可能可以補00或ff試試。

froce 補零可以 /images/emoticon/emoticon42.gif

froce iT邦大師 1 級 ‧ 2020-08-10 13:58:22 檢舉

因為查了一下好像正常密碼學都是補0或補f比較多...
這串我也學了很多。哈

/images/emoticon/emoticon41.gif

5
froce
iT邦大師 1 級 ‧ 2020-08-10 00:15:58
16進位:a7  55  dd  b4  24  d7  7f  7f  6e  52  fb  9e  82  cc  89  7f
10進位:167 85  221 180 36  215 127 127 187 223 198 180 87  88  112 146

這樣看懂了嗎?

test='A755DDB424D77F7FBBDFC6B457587092'
test=b'a755ddb424d77f7f6e52fb9e82cc897f'

這兩個字串是不同的。
你用的套件有寫:

# For Python3, you'll need to use bytes, i.e.:
#   data = b"Please encrypt my data"
#   k = pyDes.des(b"DESCRYPT", pyDes.CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
zxc512034 iT邦新手 5 級 ‧ 2020-08-10 01:13:23 檢舉
16進位:a7  55  dd  b4  24  d7  7f  7f  6e  52  fb  9e  82  cc  89  7f

轉換不是這個嗎...

10進位:167 85  221 180 36  215 127 127 110 82 251 158 130  204  137 127

不好意思,真的不太懂樓主說的...

10進位:167 85  221 180 36  215 127 127 187 223 198 180 87  88  112 146
經過python加密後的密文是 :a755ddb424d77f7f6e52fb9e82cc897f
但是原始密文是 :A755DDB424D77F7FBBDFC6B457587092

求前輩指教...

froce iT邦大師 1 級 ‧ 2020-08-10 10:46:04 檢舉

ㄜ...果然不該在睡覺前看複雜的問題。

我用 PyCryptodome 加密的結果和 pyDes 一模一樣。
所以應該是出在 TransformFinalBlock 這個是不是有理解錯誤

zxc512034 iT邦新手 5 級 ‧ 2020-08-10 16:36:49 檢舉

感謝前輩的解答
不過小碼農米爾 Mir大大解出了我所需的資訊/images/emoticon/emoticon41.gif

4
淺水員
iT邦研究生 4 級 ‧ 2020-08-10 16:14:25

提醒一下,IV 不應該固定(例如直接用 secreKey),一般 IV 都是亂數產生,然後跟密文一起發送出去。也就是 {IV: 初始向量, cipher: 密文}。
如果 IV固定的話,那麼相同的區塊會產生相同的密文,導致有可能被分析出一些資訊。
參考:初始向量

另外,塊鏈結模式有很多種,建議了解一下。各有優缺點,安全性也不同。

最後是 padding 的問題,雖然說這邊是 zero-padding 。但是 zero-padding 對於加密二進位資料時可能會無法判別原始資料長度。

Zero padding may not be reversible if the original file ends with one or more zero bytes, making it impossible to distinguish between plaintext data bytes and padding bytes.

我習慣是用 PKCS7。

除非是維護舊專案,已經有很多舊資料了,要把 VB 的程式碼改用 python 處理。
不然建議是用正確的方式加解密。(目前比較大的問題就是 IV 那邊)

淺水員 iT邦研究生 4 級 ‧ 2020-08-10 16:29:09 檢舉

再補充一下,如果沒有規定要用 DES 的話,其實現在應該要改用 AES 了。目前普遍認為 DES 已經是不安全的了。

zxc512034 iT邦新手 5 級 ‧ 2020-08-10 16:35:05 檢舉

感謝前輩補充的知識
我目前使用python requests向目標網站爬取資料
有一部分對方使用DES加密
這才來研究了加密系統/images/emoticon/emoticon06.gif

我要發表回答

立即登入回答