我有一个用c#编写的函数,你可以传递一个ascii字符串作为密钥,以及来自数据库的加密字符串并解码数据。
我已经验证了代码的工作原理是编写一个简单的c#程序来解码数据。代码片段将键字符串转换为字节,MD5将其哈希。
C#Code Snippet,省略了一些代码,这些代码将byteHash转换为ascii字符串,以便在编译的程序中输出
key = "joetest"
byte[] byteHash = cryptoServiceProvider.ComputeHash(Encoding.ASCII.GetBytes(key));
byteHash =“f2fc0f481787cc4cbb15f7ded4412fe4”
我运行以下命令和Python3并获得相同的byteHash
key = "joetest"
encoded_key = key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest()
print(hex_key)
hex_key =“f2fc0f481787cc4cbb15f7ded4412fe4”
我已经尝试将'hex_key'编码为二进制。
我的问题是我试图将hex_key传递给2个不同的python3加密程序。 Cryptodome和pyDes。两个人都告诉我,我传了一个无效的密钥。
使用byteHash的C#代码如下
tripleDesCryptoServiceProvider.Key = byteHash;
tripleDesCryptoServiceProvider.Mode = CipherMode.ECB;
byte[] byteBuff = Convert.FromBase64String(encryptedString);
string strDecrypted = Encoding.UTF8.GetString(tripleDesCryptoServiceProvider.CreateDecryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
这一切都有效,当我将加密字符串传递给此函数时,我能够解密数据。
使用pyDes我正在使用此代码
from pyDes import *
import base64
import hashlib
my_data = "fK/jw6/25y0="
#my_data is the word 'test' encrypted with the key of 'joetest'
#This code takes the key string and converts it to an MD5 hash
my_key = "joetest"
encoded_key = my_key.encode("ascii") #Encode the data as binary data
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest() #Convert the key to an MD5 hash
encoded_hex_key = hex_key.encode() #Make the MD5 key a binary key
#Convert the Base64 encoded string to the format that the decoder wants
decoded_data = base64.b64decode(my_data)
k = triple_des(encoded_hex_key, ECB, padmode=PAD_PKCS5)
my_out = k.decrypt(decoded_data)
print("my_out")
print(my_out)
exit()
我得到的错误是:
(3destest) c:\3des-test\3destest>joe3des_test3.py
Traceback (most recent call last):
File "C:\3des-test\3destest\joe3des_test3.py", line 20, in <module>
k = triple_des(encoded_hex_key, ECB, padmode=PAD_PKCS5)
File "c:\3des-test\3destest\lib\site-packages\pyDes.py", line 710, in __init__
self.setKey(key)
File "c:\3des-test\3destest\lib\site-packages\pyDes.py", line 719, in setKey
raise ValueError("Invalid triple DES key size. Key must be either 16 or 24 bytes long")
ValueError: Invalid triple DES key size. Key must be either 16 or 24 bytes long
使用pyCryptodome,我尝试了这段代码
from Cryptodome.Cipher import DES3
import base64
import hashlib
# Converts the key string to an MD5 hash
key = "joetest"
encoded_key = key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest()
#Decodes the string to binary digits
encryptedString = base64.b64decode("fK/jw6/25y0=")
#Create the cipher to decrypt the data
cipher = DES3.new(hex_key, DES3.MODE_ECB)
decryptedString = cipher.decrypt(encryptedString)
我得到这个错误
Traceback (most recent call last):
File "C:\3des-test\3destest\joe3des_test2.py", line 16, in <module>
cipher = DES3.new(hex_key, DES3.MODE_ECB)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 174, in new
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\__init__.py", line 55, in _create_cipher
return modes[mode](factory, **kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\_mode_ecb.py", line 175, in _create_ecb_cipher
cipher_state = factory._create_base_cipher(kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 99, in _create_base_cipher
key = adjust_key_parity(key_in)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 80, in adjust_key_parity
raise ValueError("Not a valid TDES key")
ValueError: Not a valid TDES key
我的python MD5哈希是32个十六进制字符长。假设我的数学是正确的,32 * 4是128位。错误是它必须是16或24字节长。 16 * 8也是128位。所以我传递的字节串值应该是正确的。我想我错过了一些东西,但似乎无法弄明白。
更新2-Jan-2018根据下面的答案,这里是我用来确认这将解密来自数据库的数据的代码的副本。
from pyDes import *
import base64
import hashlib
#my_data is the word 'test' encrypted with the key of 'joetest'
my_data = "fK/jw6/25y0="
#This code takes the key string and converts it to an MD5 hash
my_key = "joetest"
encoded_key = my_key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
digest_key = m.digest()
#Convert the Base64 encoded string to the format that the decoder wants
decoded_data = base64.b64decode(my_data)
k = triple_des(digest_key, ECB)
my_out = k.decrypt(decoded_data)
print("my_out")
print(my_out.decode("ascii"))
这里的断开是pyDes.triple_des()
正在寻找二进制密钥,但你给它的是一个带有该密钥的十六进制表示的编码字符串。由于pyDes
不期望十六进制字符串,所以请尝试给它原始的摘要(即m.digest()
而不是m.hexdigest()
)。也不需要.encode()
。
根据定义,TripleDES意味着使用24字节密钥,例如, 192位。接受少于实际重用密钥数据的实现。
在C#中,具有128位密钥的TripleDES重用前64位来创建长度为192位的密钥。
考虑到这一点,请尝试使用以下192位密钥:
f2fc0f481787cc4cbb15f7ded4412fe4f2fc0f481787cc4c
如果这有效,我期望它,你只需修改代码就可以将前64位复制到最后。
错误
第80行,在adjust_key_parity中引发ValueError(“不是有效的TDES键”)
来自pyCryptodome中的以下代码:
79 if len(key_in) not in key_size:
80 raise ValueError("Not a valid TDES key")
..
186 # Size of a key (in bytes)
187 key_size = (16, 24)
您的密钥长度为16个字节,但是以十六进制形式传递的密钥大小为32。