C
C#7mo ago
Ronald Wayne

✅ attempting to encrypt with ECB

hello. i am trying to encrypt some data however i get different results from what im doing in python as a test here is the python code
def hexaescrypt(data, key):
""" returns hex string of aes encrypted data """
c = AES.new(key.encode(), AES.MODE_ECB)
a = b2a_hex(c.encrypt(data))
print(a)
return a
def hexaescrypt(data, key):
""" returns hex string of aes encrypted data """
c = AES.new(key.encode(), AES.MODE_ECB)
a = b2a_hex(c.encrypt(data))
print(a)
return a
and here is my recreated c# code
public static byte[] genAESCrypt(byte[] data, byte[] key)
{
using Aes myAes = Aes.Create();
myAes.Mode = CipherMode.ECB;
myAes.Padding = PaddingMode.PKCS7;
myAes.Key = key;
var encryptor = myAes.CreateEncryptor();
var encryptedBytes = encryptor.TransformFinalBlock(data, 0, data.Length);
return encryptedBytes;
}
public static byte[] genAESCrypt(byte[] data, byte[] key)
{
using Aes myAes = Aes.Create();
myAes.Mode = CipherMode.ECB;
myAes.Padding = PaddingMode.PKCS7;
myAes.Key = key;
var encryptor = myAes.CreateEncryptor();
var encryptedBytes = encryptor.TransformFinalBlock(data, 0, data.Length);
return encryptedBytes;
}
here is my starting bytes 98AD3BBBBE513C6C350912819A7A6FE4A46232396461383831623535303762343965306431393935373830356435376563A431A433353939363839A437A40000 after encryption in python 376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44 after encryption in c# B9161861D4B8C6BFFCF574172E570426A3CC72635D3D58656203B4DF436B0FE41C8A962418F61E3AB2D9B1179CFF0F727C469775A7E6C17E780AFC9A7AB3EB443D0D871C865D5449AB015558F784802F i know the python implementation is correct.
59 Replies
The Fog from Human Resources
You seem to be adding a padding in the C# version but not the Py version
Ronald Wayne
Ronald WayneOP7mo ago
iirc python auto pads i think
The Fog from Human Resources
But what mode
Ronald Wayne
Ronald WayneOP7mo ago
not sure
The Fog from Human Resources
Everything must match in order to get the same result I assume it's the padding If your AES is hashed in a third party lib maybe consider switching to a built in class
Ronald Wayne
Ronald WayneOP7mo ago
aes needs padding of / 16 bytes right? my source bytes should match that
The Fog from Human Resources
I'm not sure The iirc AES can have a variable prefix and key length as long as they match a specific pattern and length guideline
Ronald Wayne
Ronald WayneOP7mo ago
Ill have to look later as its 4am rn and ive been working on this since 1am
Anton
Anton7mo ago
Are you encrypting strings? Maybe the encoding is different
canton7
canton77mo ago
What key are you using for your test, so we can try and replicate? It also looks like the Python key is a string? (From the .encode()). You don't show how you're turning the C# string into a byte array
Ronald Wayne
Ronald WayneOP7mo ago
The previous function already returns a byte array
canton7
canton77mo ago
What's "the previous function"?
Ronald Wayne
Ronald WayneOP7mo ago
Im calculating a byte array given some other data In that other function
canton7
canton77mo ago
OK, and do you want to share that function with us, so that we can see if it does the same as the Python code does? The key being different is one possible cause of your problem Also:
What key are you using for your test, so we can try and replicate?
Ronald Wayne
Ronald WayneOP7mo ago
Ive already verified the bytearrays are the same. I will get the key soon but i havent been able to get to my pc yet
Shazanman
Shazanman7mo ago
I think you meant achieve deterministic AES encryption?
canton7
canton77mo ago
I've no idea what that means...
Shazanman
Shazanman7mo ago
You need to use specific modes which allow IV inputs
canton7
canton77mo ago
ECB doesn't use an IV
Shazanman
Shazanman7mo ago
yes that's the issue
canton7
canton77mo ago
Is it?
Shazanman
Shazanman7mo ago
well if he's trying to achieve deteministic encryption Comparing output from AES encryption is useless imo Isn't encryption supposed to be getting random data in the first place?
canton7
canton77mo ago
AES is always deterministic. The fact that he hasn't set the IV shouldn't be an issue, as ECB doesn't use the IV No. If you encrypt the same thing with the same key and same parameters, you should get identical output
Shazanman
Shazanman7mo ago
but are the modes same and those parameters?
canton7
canton77mo ago
Obviously something is different, as the output is different
Ronald Wayne
Ronald WayneOP7mo ago
the key is "jo6aey6haid2Teih"
Shazanman
Shazanman7mo ago
and both implementations use the same key?
Ronald Wayne
Ronald WayneOP7mo ago
yeah
canton7
canton77mo ago
@literally a cat Is that how you're turning the key string into bytes in your "other function"?
Ronald Wayne
Ronald WayneOP7mo ago
im using Encoding.UTF8.GetBytes("jo6aey6haid2Teih") for the key ok so by default python's ecb mode does not apply padding wait a sec i think my previous function might be incorrect here was the python source
def genurlkey(songid, md5origin, mediaver=4, fmt=1):
""" Calculate the download url given the songid, origin and media+format """
data_concat = b'\xa4'.join(_ for _ in [md5origin.encode(),
str(fmt).encode(),
str(songid).encode(),
str(mediaver).encode()])
data = b'\xa4'.join([md5hex(data_concat), data_concat]) + b'\xa4'
if len(data) % 16 != 0:
data += b'\0' * (16 - len(data) % 16)
print(data)
print(len(data))
return hexaescrypt(data, "jo6aey6haid2Teih")
def genurlkey(songid, md5origin, mediaver=4, fmt=1):
""" Calculate the download url given the songid, origin and media+format """
data_concat = b'\xa4'.join(_ for _ in [md5origin.encode(),
str(fmt).encode(),
str(songid).encode(),
str(mediaver).encode()])
data = b'\xa4'.join([md5hex(data_concat), data_concat]) + b'\xa4'
if len(data) % 16 != 0:
data += b'\0' * (16 - len(data) % 16)
print(data)
print(len(data))
return hexaescrypt(data, "jo6aey6haid2Teih")
c# rewrite wait its too long for discord
Ronald Wayne
Ronald WayneOP7mo ago
C# Online Compiler | .NET Fiddle
Test your C# code online with .NET Fiddle code editor.
Ronald Wayne
Ronald WayneOP7mo ago
debug output
No description
Ronald Wayne
Ronald WayneOP7mo ago
top is py bottom is c#
canton7
canton77mo ago
md5Hash and data are different between py and C# there? Python, for some awful reason, renders bytes in a bytestring as ASCII chars if it can. So b'12' is not hex '12', it's hex '31-32' That could just be a change in how you're printing those strings though, and since you haven't shared that code, I can't check
Ronald Wayne
Ronald WayneOP7mo ago
For python im just printing all variables with .encode and c# bitconverter.tostring
The Fog from Human Resources
Python Bad on Gang
canton7
canton77mo ago
Could you please share your full exact code?
Ronald Wayne
Ronald WayneOP7mo ago
Console.WriteLine("md5originBytes: " + BitConverter.ToString(md5originBytes));
Console.WriteLine("fmtBytes: " + BitConverter.ToString(fmtBytes));
Console.WriteLine("songidBytes: " + BitConverter.ToString(songidBytes));
Console.WriteLine("mediaverBytes: " + BitConverter.ToString(mediaverBytes));
Console.WriteLine("data_concat: " + BitConverter.ToString(data_concat));
Console.WriteLine("md5Hash: " + BitConverter.ToString(md5.ComputeHash(data_concat)));
Console.WriteLine("data: " + BitConverter.ToString(data));
Console.WriteLine("append: " + BitConverter.ToString(append));
Console.WriteLine("paddedData: " + BitConverter.ToString(paddedData));
Console.WriteLine("Length: " + paddedData.Length);
Console.WriteLine("md5originBytes: " + BitConverter.ToString(md5originBytes));
Console.WriteLine("fmtBytes: " + BitConverter.ToString(fmtBytes));
Console.WriteLine("songidBytes: " + BitConverter.ToString(songidBytes));
Console.WriteLine("mediaverBytes: " + BitConverter.ToString(mediaverBytes));
Console.WriteLine("data_concat: " + BitConverter.ToString(data_concat));
Console.WriteLine("md5Hash: " + BitConverter.ToString(md5.ComputeHash(data_concat)));
Console.WriteLine("data: " + BitConverter.ToString(data));
Console.WriteLine("append: " + BitConverter.ToString(append));
Console.WriteLine("paddedData: " + BitConverter.ToString(paddedData));
Console.WriteLine("Length: " + paddedData.Length);
print("md5originBytes:", md5origin.encode())
print("fmtBytes:", str(fmt).encode())
print("songidBytes:", str(songid).encode())
print("mediaverBytes:", str(mediaver).encode())
print("data_concat:", data_concat)
print("md5Hash:", md5hex(data_concat))
print("data:", data)
print("Padded data length:", len(data))
print("md5originBytes:", md5origin.encode())
print("fmtBytes:", str(fmt).encode())
print("songidBytes:", str(songid).encode())
print("mediaverBytes:", str(mediaver).encode())
print("data_concat:", data_concat)
print("md5Hash:", md5hex(data_concat))
print("data:", data)
print("Padded data length:", len(data))
canton7
canton77mo ago
OK, so you genuinely do print the data_concat in a different way Having a mix of str(...).encode() and not is really quite confusing there!
Ronald Wayne
Ronald WayneOP7mo ago
lemme make them all str.encode and rerun it
md5originBytes: b'b29da881b5507b49e0d19957805d57ec'
fmtBytes: b'1'
songidBytes: b'3599689'
mediaverBytes: b'7'
data_concat: b"b'b29da881b5507b49e0d19957805d57ec\\xa41\\xa43599689\\xa47'"
md5Hash: b"b'98ad3bbbbe513c6c350912819a7a6fe4'"
data: b"b'98ad3bbbbe513c6c350912819a7a6fe4\\xa4b29da881b5507b49e0d19957805d57ec\\xa41\\xa43599689\\xa47\\xa4\\x00\\x00'"
Padded data length: 80
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
md5originBytes: b'b29da881b5507b49e0d19957805d57ec'
fmtBytes: b'1'
songidBytes: b'3599689'
mediaverBytes: b'7'
data_concat: b"b'b29da881b5507b49e0d19957805d57ec\\xa41\\xa43599689\\xa47'"
md5Hash: b"b'98ad3bbbbe513c6c350912819a7a6fe4'"
data: b"b'98ad3bbbbe513c6c350912819a7a6fe4\\xa4b29da881b5507b49e0d19957805d57ec\\xa41\\xa43599689\\xa47\\xa4\\x00\\x00'"
Padded data length: 80
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
huh
canton7
canton77mo ago
Can you copy the C# strings as text as well, so I can compare, without having to open/close an image
Ronald Wayne
Ronald WayneOP7mo ago
[un@archlinux Debug]$ mono app.exe
md5originBytes: 62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63
fmtBytes: 31
songidBytes: 33-35-39-39-36-38-39
mediaverBytes: 37
data_concat: 62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37
md5Hash: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4
data: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37
append: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37-A4
paddedData: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37-A4-00-00
Length: 64
Final Data:
0x98 0xad 0x3b 0xbb 0xbe 0x51 0x3c 0x6c 0x35 0x09 0x12 0x81 0x9a 0x7a 0x6f 0xe4 0xa4 0x62 0x32 0x39 0x64 0x61 0x38 0x38 0x31 0x62 0x35 0x35 0x30 0x37 0x62 0x34 0x39 0x65 0x30 0x64 0x31 0x39 0x39 0x35 0x37 0x38 0x30 0x35 0x64 0x35 0x37 0x65 0x63 0xa4 0x31 0xa4 0x33 0x35 0x39 0x39 0x36 0x38 0x39 0xa4 0x37 0xa4 0x00 0x00
64
AS COMBINED
98AD3BBBBE513C6C350912819A7A6FE4A46232396461383831623535303762343965306431393935373830356435376563A431A433353939363839A437A40000
encrypting
B9161861D4B8C6BFFCF574172E570426A3CC72635D3D58656203B4DF436B0FE41C8A962418F61E3AB2D9B1179CFF0F727C469775A7E6C17E780AFC9A7AB3EB44
[un@archlinux Debug]$ mono app.exe
md5originBytes: 62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63
fmtBytes: 31
songidBytes: 33-35-39-39-36-38-39
mediaverBytes: 37
data_concat: 62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37
md5Hash: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4
data: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37
append: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37-A4
paddedData: 98-AD-3B-BB-BE-51-3C-6C-35-09-12-81-9A-7A-6F-E4-A4-62-32-39-64-61-38-38-31-62-35-35-30-37-62-34-39-65-30-64-31-39-39-35-37-38-30-35-64-35-37-65-63-A4-31-A4-33-35-39-39-36-38-39-A4-37-A4-00-00
Length: 64
Final Data:
0x98 0xad 0x3b 0xbb 0xbe 0x51 0x3c 0x6c 0x35 0x09 0x12 0x81 0x9a 0x7a 0x6f 0xe4 0xa4 0x62 0x32 0x39 0x64 0x61 0x38 0x38 0x31 0x62 0x35 0x35 0x30 0x37 0x62 0x34 0x39 0x65 0x30 0x64 0x31 0x39 0x39 0x35 0x37 0x38 0x30 0x35 0x64 0x35 0x37 0x65 0x63 0xa4 0x31 0xa4 0x33 0x35 0x39 0x39 0x36 0x38 0x39 0xa4 0x37 0xa4 0x00 0x00
64
AS COMBINED
98AD3BBBBE513C6C350912819A7A6FE4A46232396461383831623535303762343965306431393935373830356435376563A431A433353939363839A437A40000
encrypting
B9161861D4B8C6BFFCF574172E570426A3CC72635D3D58656203B4DF436B0FE41C8A962418F61E3AB2D9B1179CFF0F727C469775A7E6C17E780AFC9A7AB3EB44
canton7
canton77mo ago
What's going on there with data_concat, md5Hash, and data? The b"b'....'"?
Ronald Wayne
Ronald WayneOP7mo ago
thats from the str(...).encode
The Fog from Human Resources
atp i think python is giving you the wrong result :stare:
canton7
canton77mo ago
Ack, this is really frustrating, because you still aren't sharing your full code, so every time I spend time picking up on something, it's due to some code which you haven't shared So I'm on the edge of just giving up -- I've wasted a bunch of time on this already
Ronald Wayne
Ronald WayneOP7mo ago
ok ill just share my functions and their results just straight up gimme a sec
canton7
canton77mo ago
I really need to be able to run both Python and C# side by side, and spot where in the process the difference is happening But you keep changing what your MCVE is
Ronald Wayne
Ronald WayneOP7mo ago
ok
from Crypto.Hash import MD5
from binascii import a2b_hex, b2a_hex
from Crypto.Cipher import AES
def md5hex(data):
""" return hex string of md5 of the given string """
# type(data): bytes
# returns: bytes
h = MD5.new()
h.update(data)
return b2a_hex(h.digest())
def hexaescrypt(data, key):
c = AES.new(key.encode(), AES.MODE_ECB)
a = b2a_hex(c.encrypt(data))
print(a)
return a
def genurlkey(songid, md5origin, mediaver=4, fmt=1):
data_concat = b'\xa4'.join(_ for _ in [md5origin.encode(),
str(fmt).encode(),
str(songid).encode(),
str(mediaver).encode()])
data = b'\xa4'.join([md5hex(data_concat), data_concat]) + b'\xa4'
if len(data) % 16 != 0:
data += b'\0' * (16 - len(data) % 16)
print("md5originBytes:", md5origin.encode())
print("fmtBytes:", str(fmt).encode())
print("songidBytes:", str(songid).encode())
print("mediaverBytes:", str(mediaver).encode())
print("data_concat:", data_concat)
print("md5Hash:", md5hex(data_concat))
print("data:", data)
print("Padded data length:", len(data))
return hexaescrypt(data, "jo6aey6haid2Teih")


print(genurlkey("3599689","b29da881b5507b49e0d19957805d57ec",7,1))
from Crypto.Hash import MD5
from binascii import a2b_hex, b2a_hex
from Crypto.Cipher import AES
def md5hex(data):
""" return hex string of md5 of the given string """
# type(data): bytes
# returns: bytes
h = MD5.new()
h.update(data)
return b2a_hex(h.digest())
def hexaescrypt(data, key):
c = AES.new(key.encode(), AES.MODE_ECB)
a = b2a_hex(c.encrypt(data))
print(a)
return a
def genurlkey(songid, md5origin, mediaver=4, fmt=1):
data_concat = b'\xa4'.join(_ for _ in [md5origin.encode(),
str(fmt).encode(),
str(songid).encode(),
str(mediaver).encode()])
data = b'\xa4'.join([md5hex(data_concat), data_concat]) + b'\xa4'
if len(data) % 16 != 0:
data += b'\0' * (16 - len(data) % 16)
print("md5originBytes:", md5origin.encode())
print("fmtBytes:", str(fmt).encode())
print("songidBytes:", str(songid).encode())
print("mediaverBytes:", str(mediaver).encode())
print("data_concat:", data_concat)
print("md5Hash:", md5hex(data_concat))
print("data:", data)
print("Padded data length:", len(data))
return hexaescrypt(data, "jo6aey6haid2Teih")


print(genurlkey("3599689","b29da881b5507b49e0d19957805d57ec",7,1))
this outputs
md5originBytes: b'b29da881b5507b49e0d19957805d57ec'
fmtBytes: b'1'
songidBytes: b'3599689'
mediaverBytes: b'7'
data_concat: b'b29da881b5507b49e0d19957805d57ec\xa41\xa43599689\xa47'
md5Hash: b'98ad3bbbbe513c6c350912819a7a6fe4'
data: b'98ad3bbbbe513c6c350912819a7a6fe4\xa4b29da881b5507b49e0d19957805d57ec\xa41\xa43599689\xa47\xa4\x00\x00'
Padded data length: 80
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
md5originBytes: b'b29da881b5507b49e0d19957805d57ec'
fmtBytes: b'1'
songidBytes: b'3599689'
mediaverBytes: b'7'
data_concat: b'b29da881b5507b49e0d19957805d57ec\xa41\xa43599689\xa47'
md5Hash: b'98ad3bbbbe513c6c350912819a7a6fe4'
data: b'98ad3bbbbe513c6c350912819a7a6fe4\xa4b29da881b5507b49e0d19957805d57ec\xa41\xa43599689\xa47\xa4\x00\x00'
Padded data length: 80
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
b'376bb7559e97f260b449928cac9a73b9c73597a4fa55a392d77218f357078073a3cc72635d3d58656203b4df436b0fe41c8a962418f61e3ab2d9b1179cff0f727c469775a7e6c17e780afc9a7ab3eb44'
Ronald Wayne
Ronald WayneOP7mo ago
C# Online Compiler | .NET Fiddle
Test your C# code online with .NET Fiddle code editor.
canton7
canton77mo ago
Well there's one difference. In the python you do data = b'\xa4'.join([md5hex(data_concat), data_concat]) + b'\xa4', but in the C# you do byte[] md5originBytes = Encoding.UTF8.GetBytes(track_hash); Or wait, I might be confused Ah no sorry, the C# version is md5.ComputeHash(data_concat) So the python side takes the hex string of the md5, but the C# side takes the raw bytes
Ronald Wayne
Ronald WayneOP7mo ago
should i be doing BitConverter.ToString(md5.ComputeHash(data_concat)) in the list then? wait no yup that was it getting 376BB7559E97F260B449928CAC9A73B9C73597A4FA55A392D77218F357078073A3CC72635D3D58656203B4DF436B0FE41C8A962418F61E3AB2D9B1179CFF0F727C469775A7E6C17E780AFC9A7AB3EB44 from c# now thank you sm and sorry for wasting your time on this lmfao
canton7
canton77mo ago
Cool, glad you found it! So the statement:
here is my starting bytes 98AD3BBBBE513C6C350912819A7A6FE4A46232396461383831623535303762343965306431393935373830356435376563A431A433353939363839A437A40000
Was wrong?
Shazanman
Shazanman7mo ago
looks like it was wrong
Ronald Wayne
Ronald WayneOP7mo ago
Yeah
canton7
canton77mo ago
Cool. I wasted about an hour trying to find that, based on the information you gave >< Next time, please make sure that the question is correct!

Did you find this page helpful?